From 6b30bbef6d426226d1f0025c9debd78d8f3d193c Mon Sep 17 00:00:00 2001
From: zoharsan where
The first, and only the first, argument of the rank() function
determines whether a document is a match,
but all arguments are used for calculating rank features. The rank operator
- is useful for boosting documents based on the presence of certain terms without impacting matching or retrieval logic.
+ is useful for boosting documents based on the presence of certain conditions without impacting matching or retrieval logic.
where rank(a contains "A", b contains "B", c contains "C")
- It's also useful in hybrid search use cases. See blog post - for usage examples. For example, retrieve using the nearestNeighbor query operator - as the first argument and have matching features calculated for the other arguments. + rank() takes any number of arguments. + Arguments after the first never affect which documents match: + they can neither exclude documents from, nor add documents to, the result set. + Any query operator can be used in these arguments, including + in, numeric ranges and grouped conditions:
-where rank(nearestNeighbor(field, queryVector), a contains "A", b contains "B", c contains "C")
+where rank(userQuery(),
+ country in ("italy", "france"),
+ range(price, 0, 1000),
+ (is_new = true and range(rating, 4, 5)))
+
+ Observing the ranking-only arguments:
+ terms in arguments after the first expose match information to
+ rank features like ordinary query terms:
+ use matches(field) for a match indicator.
+ In the example above, matches(country) is 1 for documents with
+ country italy or france, and matches(price) is 1 for documents
+ priced 1000 or less, so a rank profile can boost with e.g.
+ nativeRank + 3.0 * matches(country) + 1.0 * matches(price).
+ Text features like bm25 and
+ fieldMatch require index fields with position data;
+ operators such as in and numeric ranges are visible to
+ matches() but do not contribute to text features.
+
+ Several conditions using the same field:
+ matches(field) is 1 if any query term on the field
+ matched, so it cannot distinguish between multiple conditions on the same
+ field. Use matches(field, n) to test the n'th query term instead,
+ where n counts the query's terms in order, starting from 0:
+
+where rank(title contains "vacation package",
+ country in ("italy"),
+ country in ("norway"))
+
+ + Here, term 0 is the title term, term 1 the italy condition and term 2 the + norway condition, so this rank profile boosts italy documents by 3 + and norway documents by 1: +
+
+first-phase {
+ expression: nativeRank + 3.0 * matches(country, 1) + 1.0 * matches(country, 2)
+}
+
+
+ Note that the term numbering follows the query structure:
+ adding, removing or reordering query terms changes the indexes,
+ so rank profiles using matches(field, n) must be kept in sync
+ with the queries sent.
+
+ Grouped conditions are evaluated as a unit: + terms inside a grouped ranking-only argument expose match information + only for documents where the whole condition is true. + This makes a grouped condition usable as a single boost rule, + observable through any of its fields not used elsewhere in the query: +
+
+where rank(userQuery(),
+ (country in ("italy") and range(price, 0, 1000)))
+
+
+ Here, matches(price) is 1 only for documents that are both
+ from italy and priced 1000 or less - a document satisfying only
+ one of the two conditions gets no match information from this argument.
+ This rank profile hence boosts documents satisfying the full rule:
+
+first-phase {
+ expression: nativeRank + 3.0 * matches(price)
+}
+
+
+ Negations are not observable:
+ only positively matching terms expose match information.
+ A ranking-only argument consisting of only a negation, such as
+ rank(userQuery(), !(country in ("norway"))), matches correctly
+ but cannot be observed by any rank feature - the negated term does not
+ match precisely the documents where the condition is true.
+ To boost on a negative condition, state it positively in the query
+ and invert it in the ranking expression:
+
+where rank(userQuery(), country in ("norway"))
+
+
+first-phase {
+ expression: nativeRank + 100 * (1 - matches(country))
+}
+
+ {% include note.html content='A ranking-only argument only affects ranking
+ if the selected rank profile reads it, using a rank feature such as
+ matches(field) over one of its fields.
+ Arguments not read by any rank feature are removed from query execution:
+ they have no cost, but also no effect.' %}