Elasticsearch в типа bool запроса сочетать необходимо с или
в настоящее время я пытаюсь перенести приложение на основе solr в elasticsearch.
у меня есть этот lucene запрос
((
name:(+foo +bar)
OR info:(+foo +bar)
)) AND state:(1) AND (has_image:(0) OR has_image:(1)^100)
насколько я понимаю, это комбинация предложений MUST в сочетании с boolean или:
" получить все документы, содержащие (foo и бар в названии) или (foo и бар в информации). После этого отфильтруйте результаты по условию state=1 и повысьте документы, которые имеют изображение."
Я пытался использовать запрос bool с обязательным, но Я не могу получить boolean или в обязательные предложения. Вот что у меня есть:
GET /test/object/_search
{
"from": 0,
"size": 20,
"sort": {
"_score": "desc"
},
"query": {
"bool": {
"must": [
{
"match": {
"name": "foo"
}
},
{
"match": {
"name": "bar"
}
}
],
"must_not": [],
"should": [
{
"match": {
"has_image": {
"query": 1,
"boost": 100
}
}
}
]
}
}
}
Как вы можете видеть, должны условия для "информация" отсутствует.
есть ли у кого-нибудь решение?
большое спасибо.
** обновление **
я обновил свой запрос elasticsearch и избавился от этой оценки функции. Моя основная проблема все еще существует.
6 ответов:
- или пишется "должен"
- и пишется "должен"
- также не пишется "should_not"
пример:
вы хотите увидеть все элементы, которые являются (круглые и (красный или синий)):
{ "query": { "bool": { "must": [ { "term": {"shape": "round"}, }, { "bool": { "should": [ {"term": {"color": "red"}}, {"term": {"color": "blue"}} ] } } ] } } }вы также можете сделать более сложные версии или, например, если вы хотите, чтобы соответствовать по крайней мере 3 из 5, Вы можете указать 5 вариантов под "должен" и установить "minimum_should" из 3.
спасибо Глену Томпсону и Sebastialonso за то, что нашел, где мое гнездо было не совсем правильно раньше.
спасибо также Fatmajk за указание на то, что" термин "становится" матч " в ElasticSearch 6.
мне наконец удалось создать запрос, который делает именно то, что я хотел иметь:
отфильтрованный вложенный логический запрос. Я не уверен, почему это не документировано. Может быть, кто-то здесь может мне сказать?
вот запрос:
GET /test/object/_search { "from": 0, "size": 20, "sort": { "_score": "desc" }, "query": { "filtered": { "filter": { "bool": { "must": [ { "term": { "state": 1 } } ] } }, "query": { "bool": { "should": [ { "bool": { "must": [ { "match": { "name": "foo" } }, { "match": { "name": "bar" } } ], "should": [ { "match": { "has_image": { "query": 1, "boost": 100 } } } ] } }, { "bool": { "must": [ { "match": { "info": "foo" } }, { "match": { "info": "bar" } } ], "should": [ { "match": { "has_image": { "query": 1, "boost": 100 } } } ] } } ], "minimum_should_match": 1 } } } } }в псевдо-SQL в:
SELECT * FROM /test/object WHERE ((name=foo AND name=bar) OR (info=foo AND info=bar)) AND state=1пожалуйста, имейте в виду, что это зависит от вашего анализа поля документа и сопоставлений, как name=foo внутренне обрабатывается. Это может варьироваться от нечеткого строгого поведение.
"minimum_should_match": 1 говорит, что по крайней мере один из операторов should должен быть истинным.
Это утверждение означает, что всякий раз, когда в результирующем наборе есть документ, содержащий has_image:1, он увеличивается на коэффициент 100. Это изменяет порядок результатов.
"should": [ { "match": { "has_image": { "query": 1, "boost": 100 } } } ]весело ребята :)
используя выше я вам
[term] malformed query, expected [END_OBJECT] but found [FIELD_NAME]это сработало для меня
обновлено для Elasticsearch 5.6.4 +
{ "query": { "bool": { "must": [ {"term": {"shape": "round"}}, {"bool": { "should": [ {"term": {"color": "red"}}, {"term": {"color": "blue"}} ] }} ] } } }
недавно мне тоже пришлось решить эту проблему, и после многих проб и ошибок я придумал это (в PHP, но карты непосредственно в DSL):
'query' => [ 'bool' => [ 'should' => [ ['prefix' => ['name_first' => $query]], ['prefix' => ['name_last' => $query]], ['prefix' => ['phone' => $query]], ['prefix' => ['email' => $query]], [ 'multi_match' => [ 'query' => $query, 'type' => 'cross_fields', 'operator' => 'and', 'fields' => ['name_first', 'name_last'] ] ] ], 'minimum_should_match' => 1, 'filter' => [ ['term' => ['state' => 'active']], ['term' => ['company_id' => $companyId]] ] ] ]который сопоставляется с чем-то вроде этого в SQL:
SELECT * from <index> WHERE ( name_first LIKE '<query>%' OR name_last LIKE '<query>%' OR phone LIKE '<query>%' OR email LIKE '<query>%' ) AND state = 'active' AND company_id = <query>ключ во всем этом -
minimum_should_matchнастройка. Без этого тоfilterполностью переопределяетshould.надеюсь, это кому-то поможет!
ElasticSearch определенно ужасен, когда дело доходит до простых запросов, таких как AND, OR или IN. Но вы можете пойти умным путем и написать свой запрос как SQL, а затем преобразовать его в синтаксис ElasticSearch с помощью этого превосходного онлайн-инструмента:
SQL to ElasticSearch converter
https://www.toolsbuzz.com/query-converter
вы можете поблагодарить меня позже :)
$filterQuery = $this->queryFactory->create(QueryInterface::TYPE_BOOL, ['must' => $queries,'should'=>$queriesGeo]);на
mustвам нужно добавить массив условий запроса, с которым вы хотите работатьANDиshouldвам нужно добавить условие запроса, с которым вы хотите работатьOR.вы можете проверить это:https://github.com/Smile-SA/elasticsuite/issues/972
Comments