Эластичная релевантность поиска для запроса на основе большинства совпадений

У меня есть следующее отображение

posts":{
"properties":{
  "prop1": {
    "type": "nested",
    "properties": {
         "item1": {
            "type": "string",
            "index": "not_analyzed"
         },
         "item2": {
            "type": "string",
            "index": "not_analyzed"
         },
         "item3": {
            "type": "string",
            "index": "not_analyzed"
         }
      }
  },
  "name": {
    "type": "string",
    "index": "not_analyzed"
  }
 }
}

Рассмотрим объекты, проиндексированные следующим образом для этих сопоставлений.

{
"name": "Name1",
"prop1": [
    {
        "item1": "val1",
        "item2": "val2",
        "item3": "val3"           
    },
    {
        "item1": "val1",
        "item2": "val5",
        "item3": "val6"          
    }
  ]
}

И еще один объект

{
"name": "Name2",
"prop1": [
    {
        "item1": "val2",
        "item2": "val7",
        "item3": "val8"           
    },
    {
        "item1": "val12",
        "item2": "val9",
        "item3": "val10"          
    }
  ]
}

Теперь скажем, я хочу искать документы, которые имеют значение prop1.item1 либо «val1», либо «val2». Я также хочу, чтобы результат был отсортирован таким образом, чтобы документ с обоими значениями val1 и val2 имел больше баллов, чем документ, содержащий только одно значение «val1» или «val2».

Я пробовал следующий запрос, но, похоже, он не оценивается в зависимости от количества совпадений.

{
"query": {
   "filtered": {
    "query": {"match_all": {}},
    "filter": {
      "nested": {
        "path": "prop1",
          "filter": {
            "or": [
              {
                "and": [
                  {"term": {"prop1.item1": "val1"}},
                  {"term": {"prop1.item2": "val2"}}
                ]
              },
              {
                "and": [
                  {"term": {"prop1.item1": "val1"}},
                  {"term": {"prop1.item2": "val5"}}
                ]
              },
              {
                "and": [
                  {"term": {"prop1.item1": "val12"}},
                  {"term": {"prop1.item2": "val9"}}
                ]
              }
            ]
         }
        }
      }
    }
  }
}

Теперь, хотя он должен дать оба документа, первый документ должен иметь больше баллов, поскольку он содержит 2 вещи в фильтре, тогда как второй содержит только один. Может ли кто-нибудь помочь с правильным запросом, чтобы получить результаты, отсортированные на основе большинства совпадений?


person sriram    schedule 27.07.2014    source источник


Ответы (2)


Оценки не рассчитываются для фильтров, вместо этого используется вложенный запрос:

{
    "query": {
        "nested": {
            "score_mode": "sum",
            "path": "prop1",
            "query": {
                "bool": {
                    "should": [{
                        "bool": {
                            "must": [{
                                "match": {
                                    "prop1.item1": "val1"
                                }
                            },
                            {
                               "match": {
                                   "prop1.item2": "val2"
                               }
                           }]
                       }
                   },
                   {
                       "bool": {
                           "must": [{
                               "match": {
                                   "prop1.item1": "val1"
                               }
                           },
                           {
                               "match": {
                                   "prop1.item2": "val5"
                               }
                          }]
                      }
                  },
                  {
                      "bool": {
                          "must": [{
                              "match": {
                                  "prop1.item1": "val12"
                               }
                           },
                           {
                               "match": {
                                   "prop1.item2": "val9"
                               }
                           }]
                       }
                   }]
               }
           }
       }
   }
}
person Dan Tuffery    schedule 27.07.2014
comment
идеально. Я попробовал must внутри должен, но я не знал, что он должен иметь логическое значение :) Спасибо !! - person sriram; 27.07.2014
comment
Хотя одна беда. Я вижу, что показатель релевантности выше для документа с одним совпадением и ниже для документа с двумя совпадениями. Я думаю, это не идеально, верно? - person sriram; 27.07.2014
comment
У вас установлен режим оценки sum, как в моем примере? - person Dan Tuffery; 27.07.2014
comment
Да, это была ошибка. Вместо этого я установил его на avg :) Огромное спасибо! - person sriram; 27.07.2014

Самая большая проблема с вашим запросом заключается в том, что вы используете фильтр. Поэтому оценка не рассчитывается. Затем вы используете запрос match_all, который дает всем документам оценку 1. Замените отфильтрованный запрос запросом и используйте логический запрос вместо логического фильтра.

Надеюсь, это поможет.

person Jettro Coenradie    schedule 27.07.2014
comment
Да, это помогает. Спасибо - person sriram; 27.07.2014