Сопоставление с отсутствующими пробелами в ElasticSearch

у меня есть документы, которые я хочу индексировать в ElasticSearch, который содержит текстовое поле с именем name. В настоящее время я индексирую имя с помощью snowball анализатор. Однако, я хотел бы, чтобы сопоставить имена с пробелами. Например, документ с названием " Home Depot "должен соответствовать" homedepot"," home "и"home depot". Кроме того, документы с одним словом "ExxonMobil" должны соответствовать "exxon mobil" и "exxonmobil".

Я не могу найти правильная комбинация анализатора/фильтров для этого.

2 ответов


Я думаю, что самым прямым подходом к этой проблеме было бы применение фильтр токенов гальки, который вместо создания ngrams символов создает комбинации входящих токенов. Вы можете добавить его в свой анализатор примерно так:

filter:
    ........
    my_shingle_filter:
        type: shingle
        min_shingle_size: 2
        max_shingle_size: 3
        output_unigrams: true
        token_separator: ""

вы должны помнить о том, где этот фильтр помещается в цепочку фильтров. Вероятно, это должно произойти поздно в цепочке, после того, как все разделение/удаление/замена токенов уже произошло (т. е. после любых StopFilters, SynonymFilters, stemmers и т. д.).


в этом случае вам может потребоваться взглянуть на решение типа ngram.

Ngram делает что-то вроде этого:

учитывая текст abcd и проанализированный с помощью ngram, вы можете получить токены:

a
ab
abc
abcd
b
bc
bcd
c
cd
d

ниже-это параметр, который может работать для вас.

возможно, Вам придется повозиться с частью фильтра. Этот конкретный фильтр создает граммы длиной до 12 единиц и минимум два токена.

Теперь, если вам нужно сделать дальнейший анализ, который snowball дает вам (как вода, воды, полив все соответствующие токен воды) вам нужно будет возиться еще дальше.

        "filter": {
            "ngram_filter": {
                "type": "nGram",
                "min_gram": 2,
                "max_gram": 12
            }
        },
        "analyzer": {
            "ngram_index": {
                "filter": [
                    "lowercase",
                    "ngram_filter"
                ],
                "tokenizer": "keyword"
            },
            "ngram_search": {
                "filter": [
                    "lowercase"
                ],
                "tokenizer": "keyword"
            }
        }
    },

идея здесь состоит в indextime вы хотите создать маркеры на searchtime. Но, все нужно делать в searchtime сделать эти токены. Вам не нужно повторно применять анализатор ngram.

EDIT:

последнее, что я только что заметил, это требование: "ExxonMobil" должен соответствовать " exxon mobil"

вероятно, означает, что вам нужно сделать что-то вроде этого:

            "ngram_search": {
                "filter": [
                    "lowercase"
                ],
                "tokenizer": "whitespace"

            }

обратите внимание на добавление токенизатора "пробелов" вместо ключевого слова. Это позволяет разделить поиск на пробелы.