У меня есть индекс, который содержит название компании, аббревиатуру компании и описание того, чем занимается компания (схема индекса ниже). Пример элемента в этом документе:
{
"abbreviation": "APPL",
"name": "Apple",
"description": "Computer software and hardware"
}
Обычно пользователи вводят abbreviation
при поиске документа. Иногда они могут ввести это неправильно, и в этом случае elasticsearch отлично работает. Тем не менее, в большинстве случаев пользователи будут вводить аббревиатуру точно, и хотя они получат лучшие совпадения в верхней части ответа, вернется некоторый мусор с низкими оценками (больше 0). Я пробовал возиться с min_score
в запросах, но выбрать этот параметр сложно, потому что оценки сильно колеблются.
Есть ли способ избавиться от документов, которые не являются точным соответствием для поля abbreviation
, но все еще имеют нечеткое совпадение в качестве резервной копии на случай, если точное совпадение или пользователь ищет другие поля (например, name
и description
) не будет найден?
Вот несколько примеров:
AAPL
дает 3 результата, два из которых являются точными совпадениями для запроса, поэтому имеют довольно высокий балл, но ADP
все еще несколько похож, но явно не то, что искал пользователь.{
"abbreviation": "APPL",
"name": "Apple, Inc.",
"description": "Computer software and hardware"
},
{
"abbreviation": "APPL",
"name": "Apple, Inc.",
"description": "Computer software and hardware"
},
{
"abbreviation": "ADP",
"name": "Automatic Data Processing, Inc",
"description": "Computer software and hardware"
}
Apple
, мы снова получаем несколько наиболее релевантных записей, но затем появляются названия некоторых других компаний.{
"abbreviation": "APPL",
"name": "Apple, Inc.",
"description": "Computer software and hardware"
},
{
"abbreviation": "APPL",
"name": "Apple, Inc.",
"description": "Computer software and hardware"
},
{
"abbreviation": "CSCO",
"name": "AppDynamics (Cisco subsidiary)",
"description": "Computer software"
}
Схема документа:
{
"settings": {
"index": {
"requests.cache.enable": true
}
},
"mappings": {
"properties": {
"abbreviation_and_name": {
"type": "text",
"boost": 2
},
"abbreviation": { "type": "text", "copy_to": "abbreviation_and_name", "boost": 20 },
"name": { "type": "text", "copy_to": "abbreviation_and_name" },
"description": { "type": "text" }
}
}
}
Хорошая точка зрения. Добавление некоторых примеров
Во-первых, я, вероятно, задаюсь вопросом, почему при поиске AAPL следует возвращать следующий документ:
{
"abbreviation": "ADP",
"name": "Automatic Data Processing, Inc",
"description": "Computer software and hardware"
}
Во-вторых, я бы порекомендовал удалить критерии повышения из сопоставлений индексов, рекомендуется повышать на уровне запроса.
Но в целом, я считаю, что вам может просто понадобиться запрос ИЛИ:
{
"query": {
"bool": {
"should": [
{
"match": {
"abbreviation": {
"query": "AAPL",
"boost": 2
}
}
},
{
"multi_match": {
"query": "AAPL",
"fields": ["name", "description"],
"fuzziness": "AUTO"
}
}
]
}
}
}
Это может не дать точных результатов, как вы описали, но я считаю, что это должно отлично работать для вашего варианта использования.
В итоге я решил свою проблему, используя prefix_search
, и, похоже, это очень хорошо сработало для нашего варианта использования. Я все еще проголосовал за ваш ответ, так как было полезно увидеть multi_match
в действии.
Эй, возможно, вы могли бы привести несколько примеров запросов и как вы ожидаете, что они будут вести себя? Я хотел бы помочь, но изо всех сил пытаюсь полностью понять проблему.