ElasticSearch - 多字段模糊严格匹配
ElasticSearch - Fuzzy and strict match with multiple fields
我们想利用 ElasticSearch 为我们找到相似的对象。
假设我有一个包含 4 个字段的对象:
product_name、seller_name、seller_phone、platform_id。
相似商品在不同平台上可以有不同的商品名称和卖家名称(模糊匹配)。
而 phone 是严格的,单个变化可能会导致产生错误的记录(严格匹配)。
我们试图创建的查询将:
- 考虑我们当前记录的所有字段,或者
他们之间。
- Mandate platform_id就是我要具体看的那个。 (和)
- 模糊product_name和seller_name
- 严格匹配 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_name
和 seller_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"
}
}
}
]
}
}]
}
}
}
希望对您有所帮助
我们想利用 ElasticSearch 为我们找到相似的对象。
假设我有一个包含 4 个字段的对象: product_name、seller_name、seller_phone、platform_id。
相似商品在不同平台上可以有不同的商品名称和卖家名称(模糊匹配)。
而 phone 是严格的,单个变化可能会导致产生错误的记录(严格匹配)。
我们试图创建的查询将:
- 考虑我们当前记录的所有字段,或者 他们之间。
- Mandate platform_id就是我要具体看的那个。 (和)
- 模糊product_name和seller_name
- 严格匹配 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_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"
}
}
}
]
}
}]
}
}
}
希望对您有所帮助