Некоторое время назад я настроил поисковый индекс для веб-приложения.Одним из требований было возвращать частичные совпадения условий поиска.Например, поиск Joh
должен найти John Doe
.Самый простой способ реализовать это - добавить *
к каждому поисковому запросу, прежде чем отправлять запрос в Azure Search.Поэтому, если пользователь вводит Joh
, мы фактически запрашиваем поиск Azure для поиска Joh*
.
. Одним из ограничений этого подхода является то, что все совпадения Joh*
имеют одинаковый результат поиска.Из-за этого иногда частичное совпадение оказывается выше в результатах, чем точное совпадение.Это задокументированное поведение , так что, думаю, я мало что могу с этим поделать.Или я могу?
Хотя мой нынешний способ вернуть частичные совпадения кажется хаком, на практике он сработал достаточно хорошо, и мне не важно было выяснить, как правильно решить проблему.Теперь у меня есть время разобраться в этом, и мой инстинкт говорит, что должен быть «правильный» способ сделать это.Я прочитал слово «нграммы» здесь и там, и это, кажется, часть решения.Я мог бы найти приемлемое решение после нескольких часов хакерских атак, но если есть какой-то «стандартный» способ добиться того, чего я хочу, я бы предпочел пойти по этому пути, вместо того, чтобы использовать доморощенный взлом.Отсюда и этот вопрос.
Итак, мой вопрос: существует ли стандартный способ получения частичных совпадений в поиске Azure, при этом точные совпадения получают более высокий балл? Как изменить код ниже назаставить поиск Azure возвращать нужные мне результаты поиска?
Код
Определение индекса, возвращаемое API Azure:
{
"name": "test-index",
"defaultScoringProfile": null,
"fields": [
{
"name": "id",
"type": "Edm.String",
"searchable": false,
"filterable": true,
"retrievable": true,
"sortable": false,
"facetable": false,
"key": true,
"indexAnalyzer": null,
"searchAnalyzer": null,
"analyzer": null,
"synonymMaps": []
},
{
"name": "name",
"type": "Edm.String",
"searchable": true,
"filterable": false,
"retrievable": true,
"sortable": true,
"facetable": false,
"key": false,
"indexAnalyzer": null,
"searchAnalyzer": null,
"analyzer": null,
"synonymMaps": []
}
],
"scoringProfiles": [],
"corsOptions": null,
"suggesters": [],
"analyzers": [],
"tokenizers": [],
"tokenFilters": [],
"charFilters": []
}
Документы, опубликованные вAPI Azure:
{
"value": [
{
"@search.action": "mergeOrUpload",
"id": "1",
"name": "Joh Doe"
},
{
"@search.action": "mergeOrUpload",
"id": "2",
"name": "John Doe"
}
]
}
Поисковый запрос, опубликованный в API Azure:
{
search: "Joh*"
}
Результаты, где точное совпадение появляется вторым, а мы хотим, чтобы оно отображалось первым:
{
"value": [
{
"@search.score": 1,
"id": "2",
"name": "John Doe"
},
{
"@search.score": 1,
"id": "1",
"name": "Joh Doe"
}
]
}