Query Topics
While Sequence queries let you find recording sessions by their session-level metadata, Topic queries let you go one level deeper: you search for specific sensor channels across your entire dataset, regardless of which recording session they belong to. This is useful when you are not looking for a particular mission but for a particular kind of sensor — for example, finding every IMU channel recorded through a serial interface across all sessions.
The QueryTopic builder works the same way as QuerySequence: each .with_*() call you chain onto it adds another AND condition, and the daemon evaluates all conditions together on the server side. Only Topics that satisfy every constraint are returned.
- Python
- C++
- Rust
The C++ SDK is currently in development.
The Rust SDK is currently in development.
Querying Topics by Type and Metadata
The key filter in a Topic query is with_ontology_tag(). Every type in Mosaico's Ontology (IMU, GPS, Pressure, String, and so on) has a unique identifier called an ontology tag. Calling IMU.ontology_tag() returns that identifier, and passing it to with_ontology_tag() tells the daemon to restrict results to Topics that carry IMU data. This is how you express "I want topics of this type" without knowing their names in advance.
You can narrow the results further by chaining with_user_metadata() calls, combining a glob pattern on the metadata key with a wildcard pattern on the value. Metadata can be attached to Topics during ingestion, just as it can be attached to Sequences.
Pattern Matching: Wildcards and Glob Keys
with_name_match() and the match= keyword of with_user_metadata() accept the same lightweight glob syntax (*, ?, [], #) described in Query Sequences, applied here to Topic names instead of Sequence names — e.g. /front* matches /front/camera and /front/imu. Metadata key globs work identically.
In the example below, the query combines the IMU type filter with a metadata filter matching any key ending in .type (one level deep) whose value starts with serial. The AND semantics mean both conditions must hold simultaneously.
- Python
- C++
- Rust
from mosaicolabs import MosaicoClient, QueryTopic, IMU
with MosaicoClient.connect("localhost", 6726) as client:
results = client.query(
QueryTopic()
.with_ontology_tag(IMU.ontology_tag())
.with_user_metadata("*.type", match="serial*")
)
if results:
for item in results:
print(f"Matched Sequence: {item.sequence.name}")
print(f" Topics: {[topic.name for topic in item.topics]}")
The C++ SDK is currently in development.
The Rust SDK is currently in development.
client.query() returns None on error, or a QueryResponse, a list of QueryResponseItem objects. The structure is the same as in a Sequence query: each item.sequence gives you the parent recording session that contains the matched topics, and item.topics gives you the specific Topics within that session that satisfied your filter. This grouping is deliberate; it lets you navigate directly from a matched Topic to the session it belongs to, so you can open a handler for either the topic or the full session depending on what you need next.
topic.name returns the relative path (e.g. /front/camera/image), directly usable with other SDK methods like topic_handler() and streamers.
Key Concepts
Type safety via ontology tags. Filtering with with_ontology_tag() guarantees you get back only Topics whose data actually conforms to that schema, not just Topics that happen to be named similarly (e.g. /imu).
Generic methods using with_expression() and the .Q proxy give you access to the full operator set when the convenience methods do not cover your use case. The .Q proxy builds type-safe field paths directly from Ontology model definitions, so your queries stay consistent with the schema even as it evolves. See Multi-Domain Queries for how the proxy works.