#elasticsearch
#elasticsearch
Вопрос:
Учитывая этот документ:
{"name": "Perfect Sunny-Side Up Eggs","ingredientList": ["canola oil","eggs"]}
Как я могу создать запрос в эластичном поиске, чтобы возвращать точные совпадения в строковом массиве с заданным термином запроса «масляные яйца», пока это то, что у меня есть, но он возвращает другие нерелевантные документы:
POST /recipes/recipe/_search
{
"query": {
"match": {
"ingredientList": {
"query": [
"oil",
"eggs"
],
"operator": "and"
}
}
}
}
например, этот документ возвращается, но он не содержит «масло». Результаты должны содержать только «масло» и «яйца»:
{"name": "Quick Baked French Toast","ingredientList": ["butter","cinnamon raisin bread","eggs"]}
Комментарии:
1. Вам нужен
bool
запрос с несколькимиMust
предложениями: elastic.co/guide/en/elasticsearch/reference/current /…
Ответ №1:
Ваш запрос будет выглядеть следующим образом:
{
"query": {
"bool": {
"must": [
{
"term": {
"ingredientList": "oil"
}
},
{
"term": {
"ingredientList": "eggs"
}
}
]
}
}
}
Дает мне результаты:
{
"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"failed" : 0
},
"hits" : {
"total" : 1,
"max_score" : 1.0,
"hits" : [ {
"_index" : "ingredients",
"_type" : "recipe",
"_id" : "AVeprXFrNutW6yNguPqp",
"_score" : 1.0,
"_source" : {
"name" : "Perfect Sunny-Side Up Eggs",
"ingredientList" : [ "canola oil", "eggs" ]
}
} ]
}
}
Комментарии:
1. Большое вам спасибо!
2. Здравствуйте, я знаю, что это было опубликовано давно, но я пытаюсь сделать что-то подобное, за исключением того, что в моем случае оно должно содержать точную фразу «масло», а не «масло канолы». Вы знаете, как это сделать? Спасибо.
3. @tomfl Привет, я ищу то же самое, вы решили это?
4. @Vladimir Хм, если я правильно помню, мне пришлось изменить анализатор на
keyword
: elastic.co/guide/en/elasticsearch/reference/current /…5. чтобы
"oil"
не совпадать"canola oil"
, затем скажите"term": { "ingredientList.keyword": "oil" }
Ответ №2:
У Elastic нет API для точного сопоставления массива. Но то же самое может быть достигнуто с помощью двух методов:
-
Использование нескольких обязательных блоков (не предпочтительно)
-
Используя
terms set
запрос иscript
"query": { "bool": { "must": [ { "terms_set": { "ingredientList": { "terms": ingredients, "minimum_should_match_script": { "source": "Math.min(params.num_terms, {})".format(len(ingredients)) } } } }, { "script": { "script": { "inline": "doc['ingredientList'].length == params.list_length", "lang": "painless", "params": { "list_length": len(ingredients) } } } } ] } }