Помогите составить запрос с исключениями

Здравствуйте! Изучаю 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 я теряю фразу, где они упоминаются оба...
Надеюсь не путано объяснил :slight_smile:

А если поместить только Тараса в 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

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.