Filtering and Paging
Fulltext search and simple filtering
Use the fulltext_search field for fulltext search and simple filtering.
It supports simple_query_string capabilities of OpenSearch/Elasticsearch and the following operators:
+signifies AND operation|signifies OR operation-negates a single term"wraps a number of term to signify a phrase for searching*at the end of a term signifies a prefix query(and)signify precedence~nused after a term (for example,wnid~3), sets fuzziness, when used after a phrase, sets slop.
Details see
QueryStringQuery for Advanced Filtering (recommended for filtering)
Use the query_string_query field for advanced filtering.
It supports query_string capabilities and syntax of OpenSearch/Elasticsearch which allows advanced filtering for
specific fields.
Details see
Query Filters (legacy filtering mechanism)
Additionally, querying can be done using a limited and simplified subset of the syntax described here.
Supported Logic Operators
- $not
- $or
- $and
Examples
filter={"system.modificationDate" : "1729685234"}
... SQL equivalent ...
where `modificationDate` = '1729685234'
filter=[{"system.creationDate" : "1557394706"}, {"system.modificationDate" : "1729685234"}]
...
where `creationDate` = '1557394706' AND `modificationDate` = '1557394706'
filter={"$and" : [{"system.subtype" : "Car"}, {"$or": [{"system.id": "14"}, {"system.key": "E-Type"}]}]}
...
where `subtype` = 'Car' AND (`id` = '14' OR `key` = 'E-Type')
filter={"$and" : [{"system.subtype": "Car"}, {"data.Manufacturer" : "Jaguar"}, {"$or": [{"system.id": "14"}, {"system.key": "E-Type"}]}]}
...
where `subtype` = 'Car' AND Manufacturer = 'Jaguar' AND (`id` = '14' OR `key` = 'E-Type')
filter={"system.type": {"$not": "folder"}}
...
where NOT `type` = 'folder'
Sorting
Use the order_by parameter to control result ordering.
Format
Simple string - field name only (defaults to ascending):
"fieldPath"
JSON object - field paths as keys and sort direction as values:
{"fieldPath": "asc|desc"}
JSON object with options (needed for Elasticsearch only) - extended format with sort direction and unmapped_type:
{"fieldPath": {"order": "asc|desc", "unmapped_type": "keyword|double"}}
JSON array - multiple fields (first is primary sort, subsequent are tiebreakers):
{"data.priority": "desc", "system.creationDate": "asc"}
Examples
Sort by modification date (simple string, ascending):
system.modificationDate
Sort by modification date (newest first):
{"system.modificationDate": "desc"}
Sort by price (lowest first):
{"data.price": "asc"}
Sort by price with explicit unmapped_type (for numeric fields in Elasticsearch):
{"data.price": {"order": "asc", "unmapped_type": "double"}}
Multiple sort fields:
{"data.category": "asc", "data.price": "desc", "system.id": "asc"}
Mixed format (simple and extended):
{"data.price": {"order": "asc", "unmapped_type": "double"}, "system.id": "asc"}
The unmapped_type Parameter
When querying across multiple indices where a sort field may not exist in all indices, you can specify unmapped_type
to define how missing fields should be treated.
When to use:
- Elasticsearch: Required when sorting by numeric fields (e.g.,
data.price,data.number) to prevent "incompatible sort types" errors - OpenSearch: Optional
Supported types:
keyword- For text/string fields (default)double- For numeric fields
Why it matters:
When a field exists in some indices but not others (e.g., data.price exists in product objects but not in
asset or folder indices), Elasticsearch needs to know how to handle the missing field during sorting.
Without unmapped_type, queries may fail with "incompatible sort types" errors when the same field name has different
types across shards.
Examples:
// Numeric field sorting (Elasticsearch)
{"data.number": {"order": "asc", "unmapped_type": "double"}}
// Text field sorting
{"data.name": {"order": "asc", "unmapped_type": "keyword"}}
// Multiple fields with mixed types
{
"data.priority": {"order": "desc", "unmapped_type": "double"},
"data.name": {"order": "asc", "unmapped_type": "keyword"},
"system.id": "asc"
}
Default Behavior
If order_by is omitted, results are ordered by relevance score.
Paging
The paging can be done via the page_cursor parameter in the query. When loading the next page of a result, use the
value provided by the previous response for the page_cursor parameter. The value is available in the link header
or via the data attribute page_cursor in the response content.
Technical Details
The page_cursor has two operation modes:
- for pages below the configured max results window, it uses a numeric value and OpenSearch
fromquery. - for pages after the max results window, it uses the
search_afteroption of OpenSearch or Elasticsearch respectively.
The max results window can be configured via symfony configuration:
pimcore_data_hub_simple_rest:
# Limit of page size and offset when paging only works via page cursor (and not page numbers anymore).
max_results_window: 10000