ElasticSearch - 模糊和严格匹配多个字段

问题描述:

我们希望利用ElasticSearch找到我们类似的对象。ElasticSearch - 模糊和严格匹配多个字段

可以说我有一个包含4个字段的对象: product_name,seller_name,seller_phone,platform_id。

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

虽然,电话是严格的,一个单一的变化可能会导致产生错误的记录(严格匹配)。

什么设法创造一个查询,将:

  1. 考虑到我们各个领域的当前记录和OR它们之间 。
  2. 命令platform_id是我想要特别关注的一个。 (AND)
  3. 模糊product_name和seller_name
  4. 严格匹配电话号码或在字段之间的OR中忽略它。

如果我想在伪代码写,我会写这样的:

((PRODUCT_NAME像 'some_product_name')或(SELLER_NAME像 'some_seller_name')或(seller_phone =“some_phone “))AND(平台_id = 123)

+0

我们正在使用Searchkick宝石,因此任何解决方案或者使用它或直接查询ES将是巨大的我们:) –

+0

我使用嚼劲,我可以通过精确弹性查询具有耐嚼https://github.com/toptal/chewy弹性客户端的散列。我不知道如何用搜索引擎来实现这一点。 – user3775217

要做到精确匹配上seller_phone我正在索引没有NGRAM分析这个领域与fuzzy_query沿着product_nameseller_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" 
          } 
          } 
         } 
        ] 
       } 
      }] 
     } 
    } 
} 

希望这有助于

+0

这看起来不错。我会玩你的示例,看看我能否得到它的工作:) –

+0

顺便说一句,这是否适合你? – user3775217