Предлагает завершение поиска Elasticsearch на мультиполе с различным весом
Я использую предложение завершения в Elasticsearch, чтобы разрешить частичное совпадение запросов. В моем индексе (products_index) я хотел бы иметь возможность запрашивать как поле product_name, так и поле бренда. Вот мои отображения:
POST /product_index
mappings: {
products: {
properties: {
brand: {
type: "string",
analyzer: "english"
},
product_name: {
type: "string",
analyzer: "english"
},
id: {
type: "long"
},
lookup_count: {
type: "long"
},
suggest: {
type: "completion",
analyzer: "simple",
payloads: true,
preserve_separators: true,
preserve_position_increments: true,
max_input_length: 50
},
upc: {
type: "string"
}
}
}
}
Вот мои данные:
POST /product_index/products/2
{
id: 2,
brand: "Coca-Cola",
product_name: "Classic Coke",
suggest: {
input: [
"Classic Coke",
"Coca-Cola"
],
output: "Classic Coke - Coca-Cola",
payload: {
id: 2,
product_name: "Classic Coke",
brand: "Coca-Cola",
popularity: 10
},
weight: 0
}
}
И вот мой запрос:
POST /product_index/_search
"suggest": {
"product_suggest": {
"text": 'coca-co',
"completion": {
"field": 'suggest'
}
}
}
Это прекрасно работает, за исключением того, что я бы хотел, чтобы поле product_name имело больший вес, чем поле бренда. Есть ли способ, которым я могу достичь этого? Я посмотрел в этой статье об использовании bool запросов, но я довольно новичок в Elasticsearch и не уверен, как я могу применить это в случае подсказки завершения.
Большое спасибо!
2 ответа
Как сказал окислительно-восстановительный орган, подсказка для завершения очень проста и не поддерживает повышение количества записей. Моим решением было бы сделать два поля для подсказок, одно для бренда и одно для названия продукта:
POST /product_index
{
"mappings": {
"products": {
"properties": {
"brand": {
"type": "string",
"analyzer": "english"
},
"product_name": {
"type": "string",
"analyzer": "english"
},
"id": {
"type": "long"
},
"lookup_count": {
"type": "long"
},
"product-suggest": {
"type": "completion",
"analyzer": "simple",
"payloads": true,
"preserve_separators": true,
"preserve_position_increments": true,
"max_input_length": 50
},
"brand-suggest": {
"type": "completion",
"analyzer": "simple",
"payloads": true,
"preserve_separators": true,
"preserve_position_increments": true,
"max_input_length": 50
},
"upc": {
"type": "string"
}
}
}
}
}
При индексации заполните оба поля:
POST /product_index/products/2
{
"id": 2,
"brand": "Coca-Cola",
"product_name": "Classic Coke",
"brand-suggest": {
"input": [
"Coca-Cola"
],
"output": "Classic Coke - Coca-Cola",
"payload": {
"id": 2,
"product_name": "Classic Coke",
"brand": "Coca-Cola",
"popularity": 10
}
},
"product-suggest": {
"input": [
"Classic Coke"
],
"output": "Classic Coke - Coca-Cola",
"payload": {
"id": 2,
"product_name": "Classic Coke",
"brand": "Coca-Cola",
"popularity": 10
}
}
}
При запросе сделайте одно предложение как по бренду, так и по продукту:
POST /product_index/_search
{
"suggest": {
"product_suggestion": {
"text": "coca-co",
"completion": {
"field": "product-suggest"
}
},
"brand_suggestion": {
"text": "coca-co",
"completion": {
"field": "brand-suggest"
}
}
}
}
Вы можете добавить список предложений по брендовому предложению к предложению о продукте, удалив дубликаты, чтобы сначала иметь список предложений с только соответствующими предложениями, без дубликатов и предложений по продукту.
Другим решением будет использование запроса с повышением бренда и продукта, а не использование подсказок. Эта реализация, однако, медленнее, поскольку не использует подсказки.
Предложение по завершению на самом деле довольно ограничено с точки зрения подсчета очков: вы не можете этого сделать. Единственное, что вы можете сделать, это повысить некоторые записи, но не атрибуты внутри записи (см. weight
варианты http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-suggesters-completion.html).
Это потому, что Completion Suggester не выполняет "настоящий поиск" -> он не использует индекс. Это простой "словарь", предназначенный для выполнения расширений "префиксов" быстрее, чем с индексами + инвертированными списками.
Вы должны попробовать Algolia -> движок предназначен для ответа на поиск префиксов в реальном времени + с разными "весами" для каждого атрибута. Вот учебное пособие по реализации меню автозаполнения, предназначенного для нескольких полей: https://www.algolia.com/doc/tutorials/auto-complete