Query Service & Analytics
The Query Service provides powerful filtering, sorting, and analytics capabilities for objects in Terragnos Core. Use simple DTO-based queries or the advanced JSON DSL for complex analytics workloads.
Query Endpoints
Simple DTO Queries
For basic filtering, use the DTO-based endpoint:
GET /v1/queries/objects?typeId=traffic-signal&limit=25
Query parameters:
typeId– Filter by object typestatus– Filter by statuslimit– Maximum results (default: 100)offset– Pagination offsetsortBy– Field to sort bysortOrder–ascordesc
Advanced JSON DSL
For complex queries, use the JSON DSL:
POST /v1/queries/objects/run
Content-Type: application/json
{
"filters": [...],
"sorts": [...],
"limit": 100,
"offset": 0
}
Filter DSL
Attribute Filters
{
"field": "attributes.signalType",
"operator": "equals",
"value": "standard"
}
Operators:
equals(oreq) – Exact matchnotEquals(orne) – Not equalin– Value in arraynotIn– Value not in arraygreaterThan(orgt) – Numeric comparisongreaterThanOrEqual(orgte) – Numeric comparisonlessThan(orlt) – Numeric comparisonlessThanOrEqual(orlte) – Numeric comparisoncontains– String contains substringstartsWith– String starts withendsWith– String ends withexists– Field existsnotExists– Field doesn't existisNull– Field is nullisNotNull– Field is not null
Spatial Filters
{
"field": "geometry",
"operator": "within",
"value": {
"type": "Polygon",
"coordinates": [[[12.0, 56.0], [13.0, 56.0], [13.0, 57.0], [12.0, 57.0], [12.0, 56.0]]]
}
}
Spatial operators:
within– Geometry is within boundscontains– Geometry contains boundsintersects– Geometry intersects boundsdwithin– Within distance (meters)bbox– Bounding box intersection (minX, minY, maxX, maxY)
Combined Filters
{
"operator": "and",
"filters": [
{
"field": "typeId",
"operator": "equals",
"value": "traffic-signal"
},
{
"field": "attributes.status",
"operator": "equals",
"value": "active"
},
{
"field": "geometry",
"operator": "within",
"value": {...}
}
]
}
Logical operators:
and– All filters must matchor– Any filter must matchnot– Negate a filter
Nested logical operators:
{
"operator": "or",
"filters": [
{
"operator": "and",
"filters": [
{"field": "typeId", "operator": "equals", "value": "signal-a"},
{"field": "attributes.status", "operator": "equals", "value": "active"}
]
},
{
"operator": "and",
"filters": [
{"field": "typeId", "operator": "equals", "value": "signal-b"},
{"field": "attributes.priority", "operator": "greaterThan", "value": 5}
]
}
]
}
Sorting
{
"sorts": [
{
"field": "attributes.priority",
"order": "desc"
},
{
"field": "createdAt",
"order": "asc"
}
]
}
Sort by multiple fields. Earlier sorts take precedence.
Complete Query Example
{
"filters": [
{
"operator": "and",
"filters": [
{
"field": "typeId",
"operator": "equals",
"value": "inspection-request"
},
{
"field": "attributes.priority",
"operator": "greaterThan",
"value": 5
},
{
"field": "attributes.status",
"operator": "in",
"value": ["pending", "in-progress"]
},
{
"field": "geometry",
"operator": "dwithin",
"value": {
"type": "Point",
"coordinates": [19.04, 47.49]
},
"distanceMeters": 1000
}
]
}
],
"sorts": [
{
"field": "attributes.priority",
"order": "desc"
},
{
"field": "createdAt",
"order": "asc"
}
],
"limit": 50,
"offset": 0
}
Graph Queries
Include related objects in query results:
{
"filters": [...],
"graph": {
"objectIds": ["object-123"],
"maxDepth": 2,
"relationTypes": ["contains", "supplies"],
"relationDirection": "all"
}
}
Graph options:
objectIds– Starting objects (if not provided, uses query results)maxDepth– Maximum relation depth to traverserelationTypes– Filter by relation typesrelationDirection–outgoing,incoming, orall
Aggregations
Calculate statistics:
{
"filters": [...],
"aggregations": [
{
"field": "attributes.priority",
"function": "avg"
},
{
"field": "typeId",
"function": "count"
}
]
}
Aggregation functions:
count– Count of valuessum– Sum of numeric valuesavg– Average of numeric valuesmin– Minimum valuemax– Maximum value
Time-Travel Queries
Query historical data:
{
"filters": [...],
"asOf": "2024-01-15T10:30:00Z"
}
Returns object state at the specified point in time.
Performance Tips
- Use indexes – Ensure frequently queried fields are indexed
- Limit results – Always set reasonable
limitvalues - Filter early – Apply filters before sorting/aggregation
- Use spatial indexes – Spatial queries benefit from GIST indexes
- Cache results – Cache query results when appropriate
- Monitor query performance – Track slow queries
Integration Examples
BI Tools
Export data for analysis:
POST /v1/queries/objects/run
{
"filters": [...],
"limit": 10000
}
Reporting
Generate reports:
{
"filters": [
{
"field": "createdAt",
"operator": "greaterThan",
"value": "2024-01-01T00:00:00Z"
}
],
"aggregations": [
{
"field": "typeId",
"function": "count"
}
]
}
Real-time Dashboards
Query for dashboard data:
{
"filters": [
{
"field": "attributes.status",
"operator": "equals",
"value": "active"
}
],
"sorts": [
{
"field": "updatedAt",
"order": "desc"
}
],
"limit": 100
}