mirror of
https://github.com/elastic/elasticsearch.git
synced 2025-04-24 23:27:25 -04:00
Currently pinned queries require either the `ids` or `docs` parameter. `docs` allows pinning documents from specific indices. However for `docs` the `_index` field is always required: ``` GET test/_search { "query": { "pinned": { "organic": { "query_string": { "query": "something" } }, "docs": [ { "_id": "1" } ] } } } ``` returns an error: ``` { "error": { "root_cause": [ { "type": "parsing_exception", "reason": "[10:22] [pinned] failed to parse field [docs]", "line": 10, "col": 22 } ], "type": "parsing_exception", "reason": "[10:22] [pinned] failed to parse field [docs]", "line": 10, "col": 22, "caused_by": { "type": "x_content_parse_exception", "reason": "[10:22] [pinned] failed to parse field [docs]", "caused_by": { "type": "illegal_argument_exception", "reason": "Required [_index]" } } }, "status": 400 } ``` The proposal here is to make `_index` optional. I don't think we have a strong requirement for making `_index` required, when it was initially introduced in https://github.com/elastic/elasticsearch/pull/74873, we mostly wanted the ability to pin docs from specific indices. Making `_index` optional can give more flexibility to use a combination of pinned documents from specific indices or just document ids. This change can also help with pinned query rules. Currently pinned query rules can accept either `ids` or `docs`. If multiple pinned query rules match and they use a combination of `ids` and `docs`, we cannot build a pinned query and we would need to return an error. This is because a pinned query cannot accept both `ids` and `docs`. By making `_index` optional we would no longer need to return an error when pinned query rules use a combination of `ids` and `docs`, because we can easily translate `ids` in `docs`. The following pinned queries would be equivalent: ``` GET test/_search { "query": { "pinned": { "organic": { "query_string": { "query": "something" } }, "docs": [ { "_id": "1" } ] } } } GET test/_search { "query": { "pinned": { "organic": { "query_string": { "query": "something" } }, "ids": [1] } } } ``` The scores should be consistent when using a combination of _docs that might use _index or not - see example <details> <summary>Example </summary> ``` PUT test-1/_doc/1 { "title": "doc 1" } PUT test-1/_doc/2 { "title": "doc 2" } PUT test-2/_doc/1 { "title": "doc 1" } PUT test-2/_doc/3 { "title": "lalala" } POST test-1,test-2/_search { "query": { "pinned": { "organic": { "query_string": { "query": "lalala" } }, "docs": [ { "_id": "2", "_index": "test-1" }, { "_id": "1" } ] } } } ``` response: ``` { "took": 1, "timed_out": false, "_shards": { "total": 2, "successful": 2, "skipped": 0, "failed": 0 }, "hits": { "total": { "value": 4, "relation": "eq" }, "max_score": 1.7014124e+38, "hits": [ { "_index": "test-1", "_id": "2", "_score": 1.7014124e+38, "_source": { "title": "doc 2" } }, { "_index": "test-1", "_id": "1", "_score": 1.7014122e+38, // same score as doc with id 1 from test-2 "_source": { "title": "doc 1" } }, { "_index": "test-2", "_id": "1", "_score": 1.7014122e+38, // same score as doc with id 1 from test-1 "_source": { "title": "doc 1" } }, { "_index": "test-2", "_id": "3", "_score": 0.8025915, // organic result "_source": { "title": "lalala" } } ] } } ``` </details> For query rules, if we have two query rules that both match and use a combination of `ids` and `pinned`: ``` PUT _query_rules/test-ruleset { "ruleset_id": "test-ruleset", "rules": [ { "rule_id": "1", "type": "pinned", "criteria": [ { "type": "exact", "metadata": "query_string", "value": "country" } ], "actions": { "docs": [ { "_index": "singers", "_id": "1" } ] } }, { "rule_id": "2", "type": "pinned", "criteria": [ { "type": "exact", "metadata": "query_string", "value": "country" } ], "actions": { "ids": [ 2 ] } } ] } ``` and the following query: ``` POST singers/_search { "query": { "rule_query": { "organic": { "query_string": { "default_field": "name", "query": "country" } }, "match_criteria": { "query_string": "country" }, "ruleset_id": "test-ruleset" } } } ``` then this would get translated into the following pinned query: ``` POST singers/_search { "query": { "pinned": { "organic": { "query_string": { "default_field": "name", "query": "country" } }, "docs": [ { "_index": "singers", "_id": "1" }, {"_id": 2 } ] } } } ``` I think we can also simplify the pinned query rule so that it only receives `docs`: ``` PUT _query_rules/test-ruleset { "ruleset_id": "test-ruleset", "rules": [ { "rule_id": "1", "type": "pinned", "criteria": [ { "type": "exact", "metadata": "query_string", "value": "country" } ], "actions": { "docs": [ { "_id": "1" }, { "_id": "2", "_index": "singers" } ] } } ] } ``` |
||
---|---|---|
.. | ||
_query-template.asciidoc | ||
bool-query.asciidoc | ||
boosting-query.asciidoc | ||
combined-fields-query.asciidoc | ||
compound-queries.asciidoc | ||
constant-score-query.asciidoc | ||
dis-max-query.asciidoc | ||
distance-feature-query.asciidoc | ||
exists-query.asciidoc | ||
full-text-queries.asciidoc | ||
function-score-query.asciidoc | ||
fuzzy-query.asciidoc | ||
geo-bounding-box-query.asciidoc | ||
geo-distance-query.asciidoc | ||
geo-grid-query.asciidoc | ||
geo-polygon-query.asciidoc | ||
geo-queries.asciidoc | ||
geo-shape-query.asciidoc | ||
has-child-query.asciidoc | ||
has-parent-query.asciidoc | ||
ids-query.asciidoc | ||
intervals-query.asciidoc | ||
joining-queries.asciidoc | ||
match-all-query.asciidoc | ||
match-bool-prefix-query.asciidoc | ||
match-phrase-prefix-query.asciidoc | ||
match-phrase-query.asciidoc | ||
match-query.asciidoc | ||
minimum-should-match.asciidoc | ||
mlt-query.asciidoc | ||
multi-match-query.asciidoc | ||
multi-term-rewrite.asciidoc | ||
nested-query.asciidoc | ||
parent-id-query.asciidoc | ||
percolate-query.asciidoc | ||
pinned-query.asciidoc | ||
prefix-query.asciidoc | ||
query-string-query.asciidoc | ||
query-string-syntax.asciidoc | ||
query_filter_context.asciidoc | ||
range-query.asciidoc | ||
rank-feature-query.asciidoc | ||
regexp-query.asciidoc | ||
regexp-syntax.asciidoc | ||
rule-query.asciidoc | ||
script-query.asciidoc | ||
script-score-query.asciidoc | ||
shape-queries.asciidoc | ||
shape-query.asciidoc | ||
simple-query-string-query.asciidoc | ||
span-containing-query.asciidoc | ||
span-field-masking-query.asciidoc | ||
span-first-query.asciidoc | ||
span-multi-term-query.asciidoc | ||
span-near-query.asciidoc | ||
span-not-query.asciidoc | ||
span-or-query.asciidoc | ||
span-queries.asciidoc | ||
span-term-query.asciidoc | ||
span-within-query.asciidoc | ||
special-queries.asciidoc | ||
term-level-queries.asciidoc | ||
term-query.asciidoc | ||
terms-query.asciidoc | ||
terms-set-query.asciidoc | ||
text-expansion-query.asciidoc | ||
wildcard-query.asciidoc | ||
wrapper-query.asciidoc |