Здравствуйте! Изучаю ElasticSearch несколько месяцев, создал индекс с подобным типом документа:
"mappings": {
"news": {
"properties" : {
"title" : {"type" : "text", "fields" : {"russian" : {"type" : "text", "analyzer": "russian"}, "ukrainian" : {"type" : "text", "analyzer": "ukrainian"}}}
}
}
}
Документы в индекс поступают как на русском, так и на украинском языке. Для украинского аналайзера инсталлировал плагин.
Допустим есть такие фразы:
1: "Тарас Шевченко автор Кобзаря"
2: "Андрей Шевченко тренер сборной Украины по футболу"
3: "Тарас Шевченко и Адрей Шевченко - знаменитые украинцы"
4: "Шевченко завтра проведет прессконференцию"
Так вот, как мне написать запрос, который бы исключал определенные сочетания ключевых фраз для поиска, например, я ищу документы только о Андрее Шевченко и о Шевченко без упоминания имени (2,3,4)
Запрос
{
"query": {
"bool": {
"should": [
{"match_phrase":{"title.russian" :"Шевченко"}},
{"match_phrase":{"title.ukrainian" :"Шевченко"}}
],
"minimum_should_match":1
}
}
}
выдаст мне все документы.
Как исключить Тараса Шевченко?) Когда я использую в bool запросе must_not я теряю фразу, где они упоминаются оба...
Надеюсь не путано объяснил 
А если поместить только Тараса в must_not? Если честно, я не понимаю. что вы пытаетесь добиться. Вы не могли бы описать проблему, которую вы пытаетесь решить?
Если я сделаю так
{
"query": {
"bool": {
"must_not": [
{"match_phrase":{"title.russian" :"Тарас"}},
{"match_phrase":{"title.ukrainian" :"Тарас"}}
],
"should": [
{"match_phrase":{"title.russian" :"Шевченко"}},
{"match_phrase":{"title.ukrainian" :"Шевченко"}}
], "minimum_should_match":1
}
}
}
То запрос мне выдаст 2 и 4 документ, но я потеряю 3, а мне он нужен, так как там есть Андрей Шевченко )
Моя проблема в том, что мне нужно найти все документы, где есть Шевченко, но определенные словосочетания нужно исключить (Тарас Шевченко, музей Шевченко и т.п.), а определенные (Андрей Шевченко или просто Шевченко) должны находится запросом. Если я буду делать must_not на "Тарас" или "Тарас Шевченко" я буду терять документы, в которых они встречаются оба... Т.е. мне нужно что-то типа should_not ))
А эти словосочетания более-менее постоянные, или они меняются при каждом запросе?
Более-менее постоянные
Т.е. я могу для ключевой фразы "Шевченко" (иногда это будет фраза, а не слово, просто я привел Шевченко для примера) подобрать словосочетания, которые мне нужно исключить.
Корректно ли будет использовать такую конструкцию?
{
"min_score":0,
"query": {
"bool":{
"should": [
{"match_phrase":{"title.russian":{ "query" :"Шевченко", "boost":1}}},
{"match_phrase":{"title.russian":{ "query" :"Андрей Шевченко", "boost":1}}},
{"match_phrase":{"title.russian":{ "query" :"Тарас Шевченко", "boost":-1}}},
{"match_phrase":{"title.russian":{ "query" :"университет Шевченко", "boost":-1}}},
{"match_phrase":{"title.ukrainian":{ "query" :"Шевченко", "boost":1}}},
{"match_phrase":{"title.ukrainian":{ "query" :"Андрей Шевченко", "boost":1}}},
{"match_phrase":{"title.ukrainian":{ "query" :"Тарас Шевченко", "boost":-1}}},
{"match_phrase":{"title.ukrainian":{ "query" :"университет Шевченко", "boost":-1}}}
], "minimum_should_match":1
}
}
}
Такой запрос выдает нужные документы 2,3,4 но я не уверен, что это правильно будет работать на других документах )
А вы можете подобрать все словосочетания, которые вы хотели бы исключить из индекса при индексации?
Тогда хорошего решения, наверное, нет.
Ясно. Спасибо большое за ответы. Пока буду пользоваться вариантом с положительным и отрицательным boost