Skip to content

QQL filter predicates

WHERE describes which points qualify. It lowers to a Qdrant filter for REST, gRPC, and edge execution. It is independent from SHARD, which is request routing rather than access control.

Predicates combine with NOT, AND, and OR; precedence is predicate → NOTANDOR. Add parentheses when a mixed condition should be obvious to the reader.

QQLComparisons, membership, and boolean logicTry in playground
QUERY 'search'
FROM docs
WHERE status = 'published' AND year BETWEEN 2024 AND 2026 AND NOT tags IN ('archived', 'private') AND (score >= 0.7 OR featured = true)
LIMIT 10;
PredicateUse it for
=, !=, >, >=, <, <=Scalar equality and range comparison
BETWEEN, IN, NOT INInclusive ranges and membership sets
IS NULL, IS EMPTYMissing or empty payload values
MATCH, MATCH ANY, MATCH PHRASE, MATCH PREFIX, MATCH TOKENS, MATCH EXCEPTText and keyword-prefix payload matching
MIN SHOULD n (...)At-least-N disjunction over full filters
SLICE (total, index)Deterministic point-ID slice (parallelism / sampling)
HAS_VECTOR, VALUES_COUNTVector presence and array cardinality

The unicode operators , , and normalize to !=, >=, and <=. !=, NOT IN, IS NOT NULL, and IS NOT EMPTY all normalize to a NOT around the corresponding positive predicate. Comparison against the point id field permits =, IN, and — via the same NOT normalization — != and NOT IN; every value must be a valid point ID (an unsigned integer or a string).

Text, cardinality, and presence predicates

Section titled “Text, cardinality, and presence predicates”

MATCH covers six text forms: a plain string match, MATCH ANY over a non-empty list, MATCH PHRASE for ordered multi-token phrases, MATCH PREFIX for keyword-prefix matching (Qdrant 1.19+), MATCH TOKENS when any token of the text may match, and MATCH EXCEPT when none of the listed values may match. Field and text-index compatibility is enforced by the backend at execution time — MATCH PREFIX is most useful on a keyword field indexed with prefix = true (see Collections and indexes). VALUES_COUNT <op> <non_negative_integer> tests array cardinality.

QQLText matching, cardinality, and presenceTry in playground
QUERY 'search'
FROM docs
WHERE content MATCH 'hello world' AND tags MATCH ANY ('hello', 'world') AND description MATCH PHRASE 'vector database' AND title MATCH PREFIX 'Comp' AND summary MATCH TOKENS 'red shoes' AND status MATCH EXCEPT ('archived', 'private') AND reviews VALUES_COUNT >= 2 AND HAS_VECTOR dense AND NOT notes IS NULL
LIMIT 10;

MIN SHOULD n (...) keeps points where at least n of the operands hold. Operands are full filters, so nesting and token predicates compose. The count is at least 1; lower values fail closed with QQL-VALIDATION-MIN-SHOULD.

QQLAt-least-N disjunctionTry in playground
QUERY 'search'
FROM docs
WHERE MIN SHOULD 2 (status = 'active', priority = 'high', category = 'tech')
LIMIT 10;
QUERY 'search'
FROM docs
WHERE MIN SHOULD 1 (title MATCH TOKENS 'a b', tags MATCH EXCEPT (1, 2))
LIMIT 10;

SLICE (total, index) keeps points whose ID falls in partition index of total equal partitions. Use it to fan work across workers without random sampling. Validation requires total >= 1 and index < total; violations return QQL-VALIDATION-SLICE.

QQLPrefix match and deterministic sliceTry in playground
QUERY 'search'
FROM docs
WHERE title MATCH PREFIX 'Comp' AND SLICE (4, 1)
LIMIT 10;
QUERY 'search' FROM docs WHERE SLICE (4, 1) AND status = 'active' LIMIT 10;

Use NESTED when predicates must apply within the same object of a nested payload array. This avoids accidentally matching rating from one review and verified from another.

QQLPhrase and nested-payload matchingTry in playground
QUERY 'quality'
FROM products
WHERE description MATCH PHRASE 'machine washable' AND NESTED('reviews', rating >= 4 AND verified = true)
LIMIT 20;

Geo predicates accept structured point and shape objects. Latitude, longitude, radius, and polygon structure are validated before planning.

QQLPoints within a radiusTry in playground
QUERY 'coffee'
FROM places
WHERE location GEO_RADIUS {center: {lat: 52.52, lon: 13.405}, radius: 1500.0}
LIMIT 10;
QQLA geographic bounding boxTry in playground
QUERY 'museum'
FROM places
WHERE location GEO_BBOX {top_left: {lat: 52.54, lon: 13.36}, bottom_right: {lat: 52.49, lon: 13.45}}
LIMIT 10;

GEO_POLYGON matches points inside an exterior ring and optionally excludes holes in interiors. Every ring needs at least three points. Latitudes are validated to [-90, 90], longitudes to [-180, 180], and radii must be positive — all before planning.

QQLA polygon with an interior holeTry in playground
QUERY 'territory'
FROM places
WHERE location GEO_POLYGON {exterior: [{lat: -70.0, lon: -70.0}, {lat: 60.0, lon: -70.0}, {lat: 60.0, lon: 60.0}, {lat: -70.0, lon: 60.0}], interiors: [[{lat: -50.0, lon: -50.0}, {lat: 50.0, lon: -50.0}, {lat: 50.0, lon: 50.0}, {lat: -50.0, lon: 50.0}]]}
LIMIT 10;

See Multitenancy for the host-side policy pattern.