Сделайте запрос на поиск, чтобы все анализируемые токены ngram соответствовали - PullRequest
0 голосов
/ 16 мая 2018

Я проиндексировал некоторые данные с помощью анализатора nGram (который выдает только триграммы), чтобы решить проблему составных слов точно , как описано в руководстве ES .

Однако это не работает должным образом: соответствующий запрос на совпадение вернет все документы, для которых был найден хотя бы один nGram-токен (на слово).

Пример:

Давайте возьмем эти два проиндексированных документа в одном поле, используя анализатор nGram:

POST /compound_test/doc/_bulk
{ "index": { "_id": 1 }}
{ "content": "elasticsearch is awesome" }
{ "index": { "_id": 2 }}
{ "content": "some search queries don't perform good" }

Теперь, если я выполню следующий запрос, я получу оба результата:

"match": {
  "content": {
    "query": "awesome search",
    "minimum_should_match": "100%"
  }
}

Запрос, построенный из этого, можно выразить так:

(awe OR wes OR eso OR ome) AND (sea OR ear OR arc OR rch)

Вот почему второй документ совпадает (он содержит «некоторые» и «поиск»). Это даже соответствовало бы документу со словами, содержащими токены "som" и "rch".

На самом деле мне нужен запрос, в котором каждый анализируемый токен должен соответствовать (в лучшем случае, в зависимости от минимального соответствия), поэтому что-то вроде этого:

"match": {
  "content": {
    "query": "awe wes eso ome sea ear arc rch",
    "analyzer": "whitespace", 
    "minimum_should_match": "100%"
  }
}

.. без фактического создания этого запроса «из рук» / предварительного анализа на стороне клиента.

Все настройки и данные для воспроизведения этого поведения можно найти в https://pastebin.com/97QxfaSb

Есть ли такая возможность?

1 Ответ

0 голосов
/ 16 мая 2018

При написании вопроса я случайно нашел ответ:

Если анализатор ngram использует ngram-фильтр для генерации триграмм (как описано в руководстве), он работает так, как описано выше. (Я думаю, потому что настоящие токены - это не отдельные нграммы, а комбинация всех созданных нграмм)

Для достижения желаемого поведения анализатор должен использовать токенайзер ngram:

"tokenizer": {
  "trigram_tokenizer": {
    "type": "ngram",
    "min_gram": 3,
    "max_gram": 3,
    "token_chars": [
      "letter",
      "digit"
    ]
  }
},
"analyzer": {
  "trigrams_with_tokenizer": {
    "type": "custom",
    "tokenizer": "trigram_tokenizer" 
  }
}

Использование этого способа для создания токенов приведет к желаемому результату при обработке этого поля.

...