ElasticSearch — нечеткое и строгое соответствие с несколькими полями

Мы хотим использовать ElasticSearch для поиска похожих объектов.

Допустим, у меня есть объект с 4 полями: имя_продукта, имя_продавца, телефон_продавца, идентификатор_платформы.

Похожие продукты могут иметь разные названия продуктов и названия продавцов на разных платформах (нечеткое совпадение).

В то время как телефон является строгим, и одно изменение может привести к неправильной записи (строгое совпадение).

То, что пытались создать, - это запрос, который будет:

  1. Примите во внимание все поля, которые у нас есть для текущей записи, и ИЛИ между ними.
  2. Mandate platform_id — это то, на что я хочу обратить особое внимание. (А ТАКЖЕ)
  3. Нечеткое имя продукта и имя продавца
  4. Строго совпадайте с номером телефона или игнорируйте его в ИЛИ между полями.

Если бы я написал это в псевдокоде, я бы написал что-то вроде:

((product_name как 'some_product_name') ИЛИ (seller_name как 'some_seller_name') ИЛИ (seller_phone = 'some_phone')) И (platform_id = 123)


person Dan Benjamin    schedule 13.06.2017    source источник
comment
Мы используем гем Searchkick, поэтому любое решение, либо использующее его, либо напрямую запрашивающее ES, будет для нас отличным :)   -  person Dan Benjamin    schedule 13.06.2017
comment
я использую Chewy, где я могу передать точный эластичный хэш запроса в Chewy github.com/toptal/chewy эластичный клиент. я не уверен, как добиться этого с помощью поиска.   -  person user3775217    schedule 13.06.2017


Ответы (1)


Для точного соответствия seller_phone я индексирую это поле без анализаторов ngram вместе с fuzzy_query для product_name и seller_name

Сопоставление

PUT index111
{
  "settings": {
    "analysis": {
      "analyzer": {
        "edge_n_gram_analyzer": {
          "tokenizer": "whitespace",
          "filter" : ["lowercase",  "ednge_gram_filter"]
        }
      },
      "filter": {
      "ednge_gram_filter" : {
        "type" : "NGram",
        "min_gram" : 2,
        "max_gram": 10
      }
      }
    }
  },
  "mappings": {
    "document_type" : {
      "properties": {
        "product_name" : {
          "type": "text",
          "analyzer": "edge_n_gram_analyzer"
        },
        "seller_name" : {
          "type": "text",
          "analyzer": "edge_n_gram_analyzer"
        },
        "seller_phone" : {
          "type": "text"
        },
        "platform_id" : {
          "type": "text"
        }
      }
    }
  }
}

Индексировать документы

POST index111/document_type
{
       "product_name":"macbok",
       "seller_name":"apple",
       "seller_phone":"9988",
       "platform_id":"123"
}

Для следующего псевдозапроса sql

((product_name like 'some_product_name') OR (seller_name like 'some_seller_name') OR (seller_phone = 'some_phone')) AND (platform_id = 123)

Эластичный запрос

POST index111/_search
{
    "query": {
        "bool": {
            "must": [
              {
                "term": {
                  "platform_id": {
                    "value": "123"
                  }
                }
              },
              {
                "bool": {
                    "should": [{
                            "fuzzy": {
                                "product_name": {
                                    "value": "macbouk",
                                    "boost": 1.0,
                                    "fuzziness": 2,
                                    "prefix_length": 0,
                                    "max_expansions": 100
                                }
                            }
                        },
                        {
                            "fuzzy": {
                                "seller_name": {
                                    "value": "apdle",
                                    "boost": 1.0,
                                    "fuzziness": 2,
                                    "prefix_length": 0,
                                    "max_expansions": 100
                                }
                            }
                        },
                        {
                          "term": {
                            "seller_phone": {
                              "value": "9988"
                            }
                          }
                        }
                    ]
                }
            }]
        }
    }
}

Надеюсь это поможет

person user3775217    schedule 13.06.2017
comment
Это выглядит великолепно. Я поиграю с вашим образцом и посмотрю, смогу ли я заставить его работать :) - person Dan Benjamin; 13.06.2017