ElasticSearch - 多字段模糊严格匹配

ElasticSearch - Fuzzy and strict match with multiple fields

我们想利用 ElasticSearch 为我们找到相似的对象。

假设我有一个包含 4 个字段的对象: product_name、seller_name、seller_phone、platform_id。

相似商品在不同平台上可以有不同的商品名称和卖家名称(模糊匹配)。

而 phone 是严格的,单个变化可能会导致产生错误的记录(严格匹配)。

我们试图创建的查询将:

  1. 考虑我们当前记录的所有字段,或者 他们之间。
  2. Mandate platform_id就是我要具体看的那个。 (和)
  3. 模糊product_name和seller_name
  4. 严格匹配 phone 数字或在字段之间的 OR 中忽略它。

如果我用伪代码来写,我会这样写:

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

要在 seller_phone 上进行精确匹配,我正在为 product_nameseller_name

索引此字段而无需 ngram 分析器以及 fuzzy_query

映射

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"
                            }
                          }
                        }
                    ]
                }
            }]
        }
    }
}

希望对您有所帮助