Querying Catalogs
Demonstrates three levels of catalog search: finding topics by partial name, filtering by sensor type, and running a multi-domain query that locates specific physical events — such as IMU lateral acceleration spikes — across the entire dataset in a single server-side call.
- Python
- C++
- Rust
The C++ SDK is currently in development.
The Rust SDK is currently in development.
mosaicolabs.examples query_catalogs
Run the command with --help to see all available options.
The daemon must be running and contain data ingested via the ROS Ingestion example. The full source is on GitHub.
The Query Builder Pattern
Mosaico's query API uses fluent builder objects. Passing multiple builders to client.query() joins them with a logical AND, evaluated entirely server-side in a single round trip. Nothing is joined or filtered on the client side.
Finding Topics by Name
QueryTopic.with_name_match() performs a substring search across all topic paths in the catalog, equivalent to SQL LIKE '%pattern%'. The result is a QueryResponse grouped by sequence, so each item contains the parent session name alongside the matching topic list.
from mosaicolabs import MosaicoClient, QueryTopic
with MosaicoClient.connect(host="localhost", port=6726) as client:
results = client.query(
QueryTopic().with_name_match("image_raw")
)
if results:
for item in results:
print(f"Sequence: {item.sequence.name}")
for topic in item.topics:
print(f" {topic.name}")
Filtering by Sensor Type
with_ontology_tag() queries by the semantic type of the data rather than by path string. The query stays valid if topics are renamed, as long as the sensor type is unchanged.
from mosaicolabs import IMU, QueryTopic
results = client.query(
QueryTopic().with_ontology_tag(IMU.ontology_tag())
)
# Returns every IMU topic across all sequences in the catalog.
Multi-Domain Queries
QueryOntologyCatalog combined with QueryTopic lets you filter by both sensor type and field value in one call. The .Q proxy provides type-safe dot-notation expressions: IMU.Q.acceleration.y.geq(1.0) means "find messages where IMU y-axis acceleration is >= 1.0 m/s²". Setting include_timestamp_range=True tells the server to return the first and last timestamps of the matching window, enabling precise data slicing.
from mosaicolabs import IMU, QueryOntologyCatalog, QueryTopic
results = client.query(
QueryOntologyCatalog(
IMU.Q.acceleration.y.geq(1.0),
include_timestamp_range=True
),
QueryTopic().with_name("/front_stereo_imu/imu")
)
Replaying an Event
The timestamp_range returned by a query can be used directly to slice a data stream to the exact window containing the event. The example adds one second of padding on each side to capture the run-up and recovery.
if results:
for item in results:
for topic in item.topics:
streamer = client.sequence_handler(item.sequence.name).get_data_streamer(
topics=[topic.name],
start_timestamp_ns=topic.timestamp_range.start - 1_000_000_000,
end_timestamp_ns=topic.timestamp_range.end + 1_000_000_000,
)
for msg in streamer:
pass # process the event window