Поиск Azure - частичное совпадение фраз - PullRequest
0 голосов
/ 04 марта 2019

Я пытаюсь улучшить ранжирование результатов, возвращаемых из индекса поиска Azure.Индекс поиска в основном содержит список имен групп и участников.

Точное совпадение важно для нас, но также и частичное совпадение, но также и частичное слово в запросе.

Если я использую пример попытки найти группу под названием Black Flag.В области пользовательского ввода я набрал black fl.

. В настоящее время я структурирую запрос следующим образом: "black fl"|black fl* (точное совпадение по всей фразе и частичное совпадение по fl).

Это возвращает следующие результаты в следующем порядке:

  • Флуоресцентный черный
  • Флорентийский черный
  • Черный флаг

В настоящий моментесть одно текстовое поле, в котором выполняется поиск с использованием Standard - Lucene Analyzer.

Я смотрел на Scoring Profiles, но они не имеют отношения к такому небольшому набору данных с точки зрения полейдоступны.

Я также изучил полный поиск lucene, добавив такие слова, как ^ 10, к слову black, чтобы сделать его более важным, - и изменил строку запроса многими способами, и все это не кажетсячтобы получить эффект, которого я добиваюсь.

Я бы ожидал, что Black Flag будет соответствовать лучше, так как порядок слов более правильный, чем у результатов, которые выше него.

Есть лиспособ изменить метод оценки для обработки тего?Теперь я представляю, что я имею дело с пользовательским анализатором (https://docs.microsoft.com/en-gb/azure/search/index-add-custom-analyzers), но не совсем уверен, с чего начать или как я хотел бы, чтобы анализатор вел себя.

Любые мысли или примерыо том, как лучше всего справиться с этим сценарием, будет высоко оценено.

РЕДАКТИРОВАТЬ - Подробнее Текущее решение состоит из следующего, но оно включает в себя необходимость манипулировать результатами, которые возвращаются из поискаindex.

  1. Индекс создается следующим образом:
{
    "fields": [
        {"name": "id", "type": "Edm.String", "key": true, "filterable": false, "searchable": false, "sortable": false, "facetable": false},
        {"name": "entityId", "type": "Edm.Int64", "filterable": false, "searchable": false, "sortable": false, "facetable": false},
        {"name": "entityType", "type": "Edm.Int32", "sortable": false, "facetable": false},
        {"name": "sortableName", "type": "Edm.String", "filterable": false, "facetable": false, "searchable": false},
        {"name": "name", "type": "Edm.String", "filterable": false, "retrievable": false, "sortable": false, "facetable": false, "analyzer":"keyword_analyzer"},
        {"name": "town", "type": "Edm.String", "filterable": false, "retrievable": false, "sortable": false, "facetable": false, "analyzer":"keyword_analyzer"},
        {"name": "tags", "type": "Collection(Edm.String)", "filterable": false, "retrievable": false, "sortable": false, "facetable": false, "analyzer":"keyword_analyzer"}
    ],
    "defaultScoringProfile": "default_score",
    "scoringProfiles": [
        {
            "name": "default_score",
            "text":{
                "weights": {
                    "name": 3.5,
                    "tags": 2,
                    "town": 1
                }
            }
        }
    ],

    "analyzers":[
        {
            "name": "keyword_analyzer",
            "@odata.type":"#Microsoft.Azure.Search.CustomAnalyzer",
            "charFilters":[
                "map_dash",
                "map_space"
            ],
            "tokenizer":"keyword_tokenizer",
            "tokenFilters":[
                "asciifolding",
                "lowercase",
                "trim",
                "delimiter_filter"
            ]
        }
    ],
    "charFilters":[        
        {
           "name":"map_dash",
           "@odata.type":"#Microsoft.Azure.Search.MappingCharFilter",
           "mappings":["-=>_"]
        },
        {
           "name":"map_space",
           "@odata.type":"#Microsoft.Azure.Search.MappingCharFilter",
           "mappings":["\\u0020=>_"]
        }
     ],
    "tokenizers":[
        {
            "name": "keyword_tokenizer",
            "@odata.type":"#Microsoft.Azure.Search.KeywordTokenizerV2"
        }
    ],
    "tokenFilters":[
        {
            "name": "stopwords_filter",
            "@odata.type":"#Microsoft.Azure.Search.StopwordsTokenFilter",
            "removeTrailing": false
        },      
        {
            "name": "delimiter_filter",
            "@odata.type":"#Microsoft.Azure.Search.WordDelimiterTokenFilter",
            "generateWordParts": true,
            "generateNumberParts": true,
            "splitOnCaseChange": false,
            "preserveOriginal": true,
            "splitOnNumerics": false
        }
    ]
}

Перед загрузкой данных в индекс нам нужно его нормализовать - Black Flag становится black flag.Мы также должны удалить все предшествующие слова the, так что это означает, что The Killers становится killers - также заменяются любые нестандартные символы для удаления акцентов и т. Д.

При выполнениипоиск, в коде нам нужно теперь удалить любой предшествующий the, если он существует, и выполнить ту же нормализацию - я могу согласиться сделать это.

Затем мы создаем запрос, которыйизменяется в зависимости от количества слов в исходном запросе.

                List<string> splitQ = queryPhrase.SplitToList(" ");
                if (splitQ.Count > 0)
                {
                    if (splitQ.Count == 1)
                    {
                        search.Append($"(\"{splitQ[0]}\" || {this.EscapeSpecialCharacters(splitQ[0])}*)");
                    }
                    else
                    {
                        for (int i = 0; i < splitQ.Count; i++)
                        {
                            if (i == splitQ.Count - 1)
                            {


                                search.Append($"+{this.EscapeSpecialCharacters(splitQ[i])}*");
                            }
                            else
                                search.Append($"+\"{splitQ[i]}\"");
                        }

                        search.Insert(0, $"(\"{queryPhrase}\"||(");
                        search.Append("))");
                    }
                }

Одно слово black будет означать, что основной запрос: ("black" || black*)

Однако, как только появятся дополнительные слова, это должно измениться.black fl становится: ("black fl"||(+"black"+fl*))

Поиск в три слова будет выглядеть следующим образом: ("one two three"||(+"one"+"two"+three*))

Кроме того, мы добавим любые параметры фильтра.

Поиск отправляется по индексу с типом запроса, установленным на full

Вышеприведенные данные максимально приблизили нас к получению достойных и точных результатов.Тем не менее, оценка забита.

Обработка результатов ... Во-первых, теперь мы нормализуем оценку, заданную поисковым индексом Azure, в зависимости от поискового запроса, оценки в широком диапазонетаким образом, мы нормализуем это в процентах на основе максимального элемента оценки.

Теперь мы должны применить наш собственный enhancer к баллу на основе поля tag или name.Точное совпадение с запросом дает усилитель 5, а startswith запрос получает и улучшение 3.

Затем мы предоставляем оценку, которая использует улучшение для увеличения позиции результатов в рейтинге.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...