Elasticsearch + NEST: использовать токен-фильтр только для сравнения, но не для результатов анализаторов - PullRequest
2 голосов
/ 30 января 2020

Я хочу построить анализатор вasticsearch, который игнорирует регистры его входных данных при сравнении, но возвращает чувствительные к регистру результаты.

Это мое реальное состояние:

Мой NEST-код для создания анализатора

{ "MySynonymFilter", new SynonymTokenFilter { SynonymsPath = "Path/SynonymFile.txt", Lenient = true} },

{
    "MySynonymizer", new CustomAnalyzer
    {
        Tokenizer = "whitespace",
        Filter = new List<string> {"lowercase", "MySynonymFilter"}
    }
},

Вот как выглядит созданный выше анализатор:

"Synonymizer": {
    "filter": [
        "lowercase",
        "MySynonymFilter"
     ],
    "type": "custom",
    "tokenizer": "whitespace"
},

Мой файл синонимов ("Path / SynonymFile.txt"):

one, two, three, four => FIVE

Это фактический и желаемый результат:

Пример запроса:

localhost:port/index/_analyze
{
  "analyzer": "MySynonymizer",
  "text":      "Input"
}

Фактический результат:

Input: "one"              Output: ["five"]
Input: "One tWo THREE"    Output: ["five", "five", "five"]
Input: "one TWO foo"      Output: ["five", "five", "foo"]

Результат при удалении фильтра нижнего регистра:

Input: "one"              Output: ["FIVE"]
Input: "One tWo THREE"    Output: ["One", "tWo", "THREE"]
Input: "one TWO foo"      Output: ["FIVE", "TWO", "foo"]

Желаемый результат:

Input: "one"              Output: ["FIVE"]
Input: "One tWo THREE"    Output: ["FIVE", "FIVE", "FIVE"]
Input: "one TWO foo"      Output: ["FIVE", "FIVE", "foo"]

1 Ответ

2 голосов
/ 08 февраля 2020

Обратите внимание, что Analyze API выполняет анализ вашего входного текста и возвращает токены . Эти токены являются выходом анализатора, но это , а не конечный вывод , мы будем использовать эти токены для выполнения фактического поиска.


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

PUT /test_index
{
    "settings": {
        "index" : {
            "analysis" : {
                "filter" : {
                    "synonym" : {
                        "type" : "synonym",
                        "lenient": true,
                        "ignore_case": "true", // <-- deprecated
                        "synonyms" : ["one, two, three => FIVE"]
                    }
                }
            }
        }
    }
}

И затем вы можете анализировать текст, не используя "lowercase" фильтр токенов:

GET /test_index/_analyze
{
  "tokenizer" : "whitespace",
  "filter" : ["synonym"] ,
  "text" : "One two three" // --> result: "FIVE", "FIVE", "FIVE"
}

Таким образом, ваши синонимы будут игнорироваться case и анализатор не преобразовывал что-либо в строчные буквы ... но ignore_case устарела. Если вы попробуете этот код, вы получите следующее сообщение:

Устаревание: параметр ignore_case в фильтре synonym_graph устарел. Вместо этого вставьте строчный фильтр в цепочку фильтров перед фильтром synonym_graph.

То, чего вы хотите достичь, больше невозможно (и это имеет смысл). Если ваш поиск чувствителен к регистру, то ваши синонимы также чувствительны к регистру ... если вы хотите игнорировать регистр, используйте "lowercase" token filter ...

...