Предлагает завершение поиска 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

Другие вопросы по тегам