如何在Elasticsearch中实现符合特定规则的词/短语匹配查询?
问题描述
原始数据
[ { "name": "Apple Company" }, { "name": "Microsoft Company" } ]
预期查询与结果
查询1:
name: apple结果1:
[ { "name": "Apple Company" } ]查询2:
name: app结果2:
[ { "name": "Apple Company" } ]查询3:
name: apple com结果3:
[ { "name": "Apple Company" } ]查询4:
name: apple company结果4:
[ { "name": "Apple Company" } ]查询5:
name: company结果5:
[ { "name": "Apple Company" }, { "name": "Microsoft Company" } ]查询6:
name: ap com结果6:
[]
请问如何在Elasticsearch中实现该需求?
实现方案
1. 创建带自定义分析器的索引
先为name字段配置自定义分析器,用edge_ngram过滤器生成单词的前缀(限制前缀长度≥3,避免短前缀误匹配),同时保留完整单词的匹配能力。
创建索引的请求:
PUT /company_index { "settings": { "analysis": { "analyzer": { "name_prefix_analyzer": { "tokenizer": "standard", "filter": [ "lowercase", "name_edge_ngram" ] } }, "filter": { "name_edge_ngram": { "type": "edge_ngram", "min_gram": 3, "max_gram": 20, "side": "front" } } } }, "mappings": { "properties": { "name": { "type": "text", "analyzer": "name_prefix_analyzer", "search_analyzer": "standard" } } } }
说明:
name_prefix_analyzer:先用标准分词器拆分单词,转小写后生成每个单词从3个字符开始的前缀(比如Apple会被拆成app、appl、apple)。search_analyzer设为standard:查询时只做标准分词和小写转换,避免查询词被拆成更短的前缀,保证查询逻辑符合预期。
2. 导入测试数据
将原始数据导入索引:
POST /company_index/_bulk {"index":{}} {"name": "Apple Company"} {"index":{}} {"name": "Microsoft Company"}
3. 执行查询
使用match查询并设置operator: and,确保多个查询词必须同时匹配文档:
查询1(name: apple)
GET /company_index/_search { "query": { "match": { "name": { "query": "apple", "operator": "and" } } } }
查询2(name: app)
GET /company_index/_search { "query": { "match": { "name": { "query": "app", "operator": "and" } } } }
查询3(name: apple com)
GET /company_index/_search { "query": { "match": { "name": { "query": "apple com", "operator": "and" } } } }
查询4(name: apple company)
GET /company_index/_search { "query": { "match": { "name": { "query": "apple company", "operator": "and" } } } }
查询5(name: company)
GET /company_index/_search { "query": { "match": { "name": { "query": "company", "operator": "and" } } } }
查询6(name: ap com)
GET /company_index/_search { "query": { "match": { "name": { "query": "ap com", "operator": "and" } } } }
匹配逻辑说明
- 短前缀(如
ap):因为edge_ngram的min_gram设为3,不会生成该前缀的索引,无法匹配任何文档。 - 3字符及以上前缀(如
app、com):能匹配对应单词的前缀,返回符合条件的文档。 - 完整单词(如
apple、company):直接匹配对应单词,返回符合条件的文档。 - 多查询词(如
apple com):operator: and要求所有查询词都匹配文档,因此只有同时满足两个条件的文档才会被返回;ap com中ap无匹配,所以结果为空。
内容的提问来源于stack exchange,提问作者xuka
相关产品推荐
相关产品推荐

