Filtering & Querying
TrackVision provides powerful filtering capabilities through query parameters and filter rules. This page covers all aspects of filtering data including query parameters, filter operators, and advanced filtering techniques.
Filter Parameter
The filter parameter is used to search items in a collection that match specific conditions. Filters use a JSON structure to define rules that can be flat, relational, or complex with logical operators.
Filter Syntax
- Field — Any valid root field, relational field, or logical operator
- Operator — Any valid filter operator
- Value — Any valid static value, or dynamic variable
{
<field>: {
<operator>: <value>
}
}
Examples
Retrieve all products where product_name equals "Organic Apple Juice"
{
"product_name": {
"_eq": "Organic Apple Juice"
}
}
Retrieve all products with a GTIN matching one of a specific set
{
"gtin": {
"_in": ["09521234543217", "09521234543224", "09521234543231"]
}
}
Retrieve all products created between two dates
{
"date_created": {
"_between": ["2024-01-01", "2024-03-31"]
}
}
- REST
- GraphQL
?filter[product_name][_eq]=Organic Apple Juice
// or
?filter={ "product_name": { "_eq": "Organic Apple Juice" }}
query {
product(filter: { product_name: { _eq: "Organic Apple Juice" } }) {
id
}
}
Filter Operators
| Operator Title (in app) | Operator | Description |
|---|---|---|
| Equals | _eq | Equal to |
| Doesn't equal | _neq | Not equal to |
| Less than | _lt | Less than |
| Less than or equal to | _lte | Less than or equal to |
| Greater than | _gt | Greater than |
| Greater than or equal to | _gte | Greater than or equal to |
| Is one of | _in | Matches any of the values |
| Is not one of | _nin | Doesn't match any of the values |
| Is null | _null | Is null |
| Isn't null | _nnull | Is not null |
| Contains | _contains | Contains the substring |
| Contains (case-insensitive) | _icontains | Contains the case-insensitive substring |
| Doesn't contain | _ncontains | Doesn't contain the substring |
| Starts with | _starts_with | Starts with |
| Starts with | _istarts_with | Starts with, case-insensitive |
| Doesn't start with | _nstarts_with | Doesn't start with |
| Doesn't start with | _nistarts_with | Doesn't start with, case-insensitive |
| Ends with | _ends_with | Ends with |
| Ends with | _iends_with | Ends with, case-insensitive |
| Doesn't end with | _nends_with | Doesn't end with |
| Doesn't end with | _niends_with | Doesn't end with, case-insensitive |
| Is between | _between | Is between two values (inclusive) |
| Isn't between | _nbetween | Is not between two values (inclusive) |
| Is empty | _empty | Is empty (null or falsy) |
| Isn't empty | _nempty | Is not empty (null or falsy) |
| Intersects | _intersects [1] | Value intersects a given point |
| Doesn't intersect | _nintersects [1] | Value does not intersect a given point |
| Intersects Bounding box | _intersects_bbox [1] | Value is in a bounding box |
| Doesn't intersect bounding box | _nintersects_bbox [1] | Value is not in a bounding box |
The following operator has no Title on the Filter Interface as it is only available in validation permissions:
| Operator | Description |
|---|---|
_regex [2] | Field has to match regex |
[1] Only available on Geometry types.
[2] JavaScript "flavor" regex. Make sure to escape backslashes.
Relational Filters
You can filter based on related data by nesting field names. This works for both Many-to-One and Many-to-Many relationships.
Many-to-One Example
Filter products where the related brand name equals "TrackVision Premium":
{
"brand": {
"brand_name": {
"_eq": "TrackVision Premium"
}
}
}
Many-to-Many Example
When using M2M relationships, filters apply through the junction table. For a product collection with M2M relationship to certifications:
{
"certifications": {
"certification_id": {
"certification_type": {
"_eq": "organic"
}
}
}
}
The filter will apply to the top level items based on conditions in related items. To filter the related items themselves, use the deep parameter!
Filtering M2A Fields
For Many-to-Any fields in GraphQL, replace the : character with double underscores:
query {
product(
filter: {
related_content: {
item__documents: { # Instead of: item:documents
title: { _eq: "Safety Data Sheet" }
}
}
}
) {
id
}
}
Logical Operators
Group multiple filter rules using _and or _or logical operators. Each operator holds an array of filter rules.
Retrieve products created by the current user that are in draft, or products created by others that are active:
{
"_or": [
{
"_and": [
{
"user_created": {
"_eq": "$CURRENT_USER"
}
},
{
"status": {
"_in": ["active", "draft"]
}
}
]
},
{
"_and": [
{
"user_created": {
"_neq": "$CURRENT_USER"
}
},
{
"status": {
"_in": ["active"]
}
}
]
}
]
}
Some vs None in One-to-Many
By default, one-to-many filters use "some" logic. Override this with explicit _some and _none operators:
Fetch all products that have no certifications of type "organic":
{
"certifications": {
"_none": {
"certification_type": {
"_eq": "organic"
}
}
}
}
This fetches all products that don't have an organic certification.
Dynamic Variables
Filter against dynamic values using these variables:
$CURRENT_USER— The primary key of the currently authenticated user$CURRENT_ROLE— The primary key of the role for the currently authenticated user$CURRENT_ROLES— An array of roles containing the$CURRENT_ROLEand any roles included within it$CURRENT_POLICIES— An array of policies assigned to the user directly, or through their roles$NOW— The current timestamp$NOW(<adjustment>)— The current timestamp plus/minus a given distance, e.g.,$NOW(-1 year),$NOW(+2 hours)
In permissions, $CURRENT_USER and $CURRENT_ROLE allow specifying nested fields: $CURRENT_ROLE.name or $CURRENT_USER.avatar.filesize. This includes custom fields added to trackvision_users/trackvision_roles tables.
Note: Regular filters only support the root ID.
Other Query Parameters
Most TrackVision native API endpoints support these query parameters for filtering and manipulating data:
Fields
Choose which fields to return in the response. Supports dot notation for nested relational fields and wildcards (*).
Examples
Get all top-level fields:
*
Get all top-level fields and all second-level relational fields:
*.*
Get specific fields:
product_name,gtin
Get nested relational data:
*,brand.*
Many-To-Any Fields
For M2A fields, specify fields per collection type:
?fields=<m2a-field>:<collection-scope>.<field>
Example for a product collection with related_content pointing to different content types:
- REST
- GraphQL
GET /items/product
?fields[]=product_name
&fields[]=related_content.item:documents.title
&fields[]=related_content.item:documents.file
&fields[]=related_content.item:videos.source
query {
product {
related_content {
item {
... on documents {
title
file
}
... on videos {
source
}
}
}
}
}
For production use, request only specific fields instead of wildcards to improve performance and reduce response size.
Search
Perform text search across textual and numeric fields in a collection. Only searches root item fields.
- REST
- GraphQL
?search=Organic
query {
product(search: "Organic") {
id
product_name
}
}
Sort
Sort results by field(s). Use - prefix for descending order. Supports dot notation for nested fields.
Examples:
- Sort by creation date descending:
-date_created - Multiple sorts:
product_name,-date_created - Nested field sort:
brand.brand_name
- REST
- GraphQL
?sort=product_name,-date_created,brand.brand_name
// or
?sort[]=product_name&sort[]=-date_created&sort[]=brand.brand_name
query {
product(sort: ["product_name", "-date_created", "brand.brand_name"]) {
id
product_name
}
}
Limit
Set maximum items returned (default: 100).
- REST
- GraphQL
?limit=200
query {
product(limit: 200) {
id
product_name
}
}
Use -1 for maximum allowed items. Large requests may cause performance issues. Configure max with QUERY_LIMIT_MAX.
Offset
Skip the first n items. Used for pagination.
- REST
- GraphQL
?offset=100
query {
product(offset: 100) {
id
product_name
}
}
Page
Alternative to offset. Sets offset as limit * page. Page is 1-indexed.
- REST
- GraphQL
?page=2
query {
product(page: 2) {
id
product_name
}
}
Advanced Features
Deep Filtering
Apply query parameters to nested relational datasets using the deep parameter.
Limit nested certifications on a product to 3:
{
"certifications": {
"_limit": 3
}
}
Complex nested filtering — limit certifications and sort lots by expiry date:
{
"certifications": {
"_limit": 3,
"lots": {
"_sort": "expiry_date",
"_limit": 1
}
}
}
Filter product translations to return only the English version:
- REST
- GraphQL
?deep[translations][_filter][languages_code][_eq]=en-US
// or
?deep={ "translations": { "_filter": { "languages_code": { "_eq": "en-US" }}}}
query {
product {
translations(filter: { languages_code: { _eq: "en-US" } }) {
id
product_description
}
brand {
brand_name
}
}
}
Aliases
Rename fields on the fly and request the same nested dataset multiple times with different filters.
Request both all translations and only the French translation of a product in a single call:
- REST
- GraphQL
?alias[all_translations]=translations
&alias[french_translations]=translations
&deep[french_translations][_filter][languages_code][_eq]=fr-FR
query {
product {
french_translations: translations(filter: { languages_code: { _eq: "fr-FR" } }) {
id
product_description
}
all_translations: translations {
id
languages_code
}
}
}
Aliases only work for same-level fields. Cannot alias nested fields like field.nested.
Aggregation & Grouping
Perform calculations on sets of values:
| Function | Description |
|---|---|
count | Count items |
countDistinct | Count unique items |
sum | Sum values |
sumDistinct | Sum unique values |
avg | Average value |
avgDistinct | Average of unique values |
min | Minimum value |
max | Maximum value |
countAll | Count all (GraphQL only) |
Grouping
Group aggregations by field values for reporting like "Number of products per brand per year":
- REST
- GraphQL
?aggregate[count]=id,gtin
&groupBy[]=brand
&groupBy[]=year(date_created)
query {
product_aggregated(groupBy: ["brand", "year(date_created)"]) {
group
count {
id
gtin
}
}
}
Functions
Apply functions to transform field values in queries:
DateTime Functions
| Function | Description |
|---|---|
year | Extract year |
month | Extract month |
week | Extract week |
day | Extract day |
weekday | Extract weekday |
hour | Extract hour |
minute | Extract minute |
second | Extract second |
Array Functions
| Function | Description |
|---|---|
count | Count items in array/relation |
- REST
- GraphQL
?fields=id,product_name,month(date_created)
&filter[year(date_created)][_eq]=2024
query {
product(filter: { date_created_func: { year: { _eq: 2024 } } }) {
id
product_name
date_created_func {
month
}
}
}
Export
Save API responses to file formats:
- REST
- GraphQL
?export=csv
?export=json
?export=xml
?export=yaml
// Not Applicable