Префикс фразы соответствия Elasticsearch не соответствует всем терминам

У меня возникла проблема, из-за которой, когда я использую запрос match_phrase_prefix в Elasticsearch, он не возвращает все ожидаемые результаты, особенно когда запрос представляет собой одно слово, за которым следует одна буква.

Возьмите это сопоставление индекса (это надуманный пример для защиты конфиденциальных данных):

http://localhost:9200/test/drinks/_mapping

возвращает:

{
  "test": {
    "mappings": {
      "drinks": {
        "properties": {
          "name": {
            "type": "text"
          }
        }
      }
    }
  }
}

И среди миллионов других записей вот эти:

{
    "_index": "test",
    "_type": "drinks",
    "_id": "2",
    "_score": 1,
    "_source": {
        "name": "Johnnie Walker Black Label"
    }
},
{
    "_index": "test",
    "_type": "drinks",
    "_id": "1",
    "_score": 1,
    "_source": {
        "name": "Johnnie Walker Blue Label"
    }
}

Следующий запрос, состоящий из одного слова, за которым следуют две буквы:

POST http://localhost:9200/test/drinks/_search
{
    "query": {
        "match_phrase_prefix" : {
            "name" : "Walker Bl"
        }
    }
}

возвращает это:

{
    "took": 1,
    "timed_out": false,
    "_shards": {
        "total": 5,
        "successful": 5,
        "failed": 0
    },
    "hits": {
        "total": 2,
        "max_score": 0.5753642,
        "hits": [
            {
                "_index": "test",
                "_type": "drinks",
                "_id": "2",
                "_score": 0.5753642,
                "_source": {
                    "name": "Johnnie Walker Black Label"
                }
           },
           {
               "_index": "test",
               "_type": "drinks",
               "_id": "1",
               "_score": 0.5753642,
               "_source": {
                   "name": "Johnnie Walker Blue Label"
                }
            }
        ]
    }
}

Тогда как этот запрос с одним словом и одной буквой:

POST http://localhost:9200/test/drinks/_search
{
    "query": {
        "match_phrase_prefix" : {
            "name" : "Walker B"
        }
    }
}

не возвращает никаких результатов. Что здесь может происходить?


person Paul T Davies    schedule 08.11.2017    source источник


Ответы (1)


Я предполагаю, что вы работаете с Elasticsearch 5.0 и выше. Я думаю, что это может быть из-за значения по умолчанию max_expansions.

Как видно из документации здесь параметры max_expansions используются для управления количеством префиксов, которыми будет расширен последний термин. Значение по умолчанию — 50, и это может объяснить, почему вы найдете черный и синий с двумя первыми буквами B и L, а не только с B.

Документация довольно ясна:

Запрос match_phrase_prefix — это автозаполнение для бедняков. Он очень прост в использовании, что позволяет вам быстро начать поиск по мере ввода, но его результаты, которые обычно достаточно хороши, иногда могут сбивать с толку.

Рассмотрим строку запроса quick brown f. Этот запрос работает путем создания фразового запроса из слов «быстрый» и «коричневый» (т. е. термин «быстрый» должен существовать и за ним должен следовать термин «коричневый»). Затем он просматривает отсортированный словарь терминов, чтобы найти первые 50 терминов, начинающихся с буквы f, и добавляет эти термины в запрос фразы.

Проблема в том, что первые 50 терминов могут не включать термин fox, поэтому фаза quick brown fox не будет найдена. Обычно это не проблема, так как пользователь будет продолжать вводить буквы, пока не появится искомое слово.

Я бы не смог сказать вам, можно ли увеличить этот параметр выше 50, если вы ищете хорошие характеристики, так как я никогда не пробовал сам.

person Rlarroque    schedule 08.11.2017
comment
Один вопрос, в документации сказано, что он будет искать быстрый, за которым следует коричневый. Будет ли тогда elasticsearch искать следующие 50 (по умолчанию) терминов, которые начинаются с буквы f и которым предшествуют слова quick и brown в указанном порядке? Или просто любой термин, начинающийся с f? И в любом из предыдущих случаев, почему не возвращает результат, если есть по крайней мере 2 термина, начинающиеся с (в этом вопросе) b (синий и черный) я ожидал увидеть первые 50 терминов, по крайней мере, те два или другие должны быть показаны. Или я ошибаюсь. - person José; 08.11.2017
comment
Возможно, 50 терминов взяты из встроенного словаря, основанного на языке, используемом вашим кластером (поскольку ES поддерживает пользовательские языки), а не из другого документа, который есть в вашем индексе. Это объясняет, почему это настраиваемый параметр для запроса match_phrase_prefix и отличается от простого использования параметра размера. - person Rlarroque; 08.11.2017
comment
В моем случае ни одно из моих полей не имеет языкового свойства в сопоставлении. А как только ввожу новую букву то и результаты показываются точнее. Я использую запрос multi_match "type": "phrase_prefix", поэтому параметр max_expansions использовать нельзя. - person José; 08.11.2017
comment
Это, кажется, проблема. Поиск по индексу во время ввода решает проблему для меня: elastic.co/guide/en/elasticsearch/guide/current/ - person Paul T Davies; 09.11.2017