Skip to main content

Multi-Domain Query

Combining Sequence, Topic, and Ontology Filters

Multi-domain queries are the most powerful form of search in Mosaico. By passing multiple query builders to a single client.query() call, you instruct the daemon to evaluate all filter layers simultaneously in one round trip. This is far more efficient than running separate queries and joining results on the client side; the server does all the work and returns only what matches every condition.

There are three layers you can combine, and each one narrows the result set from a different angle:

  • QuerySequence filters at the session level. It looks at recording metadata such as the project name, robot identifier, environment conditions, or any custom tag you attached when the recording was created. Use this to restrict results to a meaningful subset of your data catalog before the other filters even run.
  • QueryTopic narrows within the matched sessions down to a specific channel. It matches on the topic name path (e.g. /front/camera/imu) and on the declared data type. This ensures you are only inspecting the right stream, not every stream in the session.
  • QueryOntologyCatalog goes one level deeper: it inspects the actual stored data values. It leverages Mosaico's ontology, the type system that gives every field a declared type and name, to evaluate expressions directly against the recorded measurements.

All three builders passed to client.query() are joined with AND. A result is returned only when a sequence, topic, and data window all satisfy every condition you specified.

The .Q Proxy

Every Ontology model in the SDK (such as IMU, GPS, String) exposes a .Q class attribute. This proxy generates type-safe field path expressions that the server can evaluate. When you write IMU.Q.acceleration.x.gt(5.0), you are saying "the X component of the acceleration vector is greater than 5.0". The IDE can autocomplete field names because .Q mirrors the structure of the ontology type, so typos in field paths are caught before the query ever runs.

The comparison operators available on a field path (.gt(), .lt(), .eq(), .between(), .match(), and others) correspond to server-side predicates. Nothing is evaluated in Python; the expression is serialised and sent to the daemon, which applies it during the scan. .match() accepts the same glob-style wildcards (*, ?, [], #) used by with_name_match() and with_user_metadata(key, match=...). See The Query Workflow for the full reference.

Understanding the Response

client.query() always returns the same QueryResponse type, which behaves as a list of QueryResponseItem objects. In a multi-domain query, each item carries:

  • item.sequence: the matched sequence (recording session) with its name and metadata
  • item.topics: the list of topics within that sequence that satisfied the Topic and OntologyCatalog conditions

Each topic also carries the time interval where the query condition held true. See Temporal Windows to extract and compare these intervals across topics and sequences.