如何使用multi-match查询实现多索引下关键词半匹配检索
实现方案
1. 跨索引查询实现
Elasticsearch原生支持单次请求查询多个索引,直接在查询接口路径中将目标索引用英文逗号分隔即可,无需分开编写两次查询语句,示例请求路径:GET /索引1,索引2/_search,也可以用通配符匹配同规则的索引,比如GET /user*,order*/_search。
2. 包含/前缀匹配man的查询实现
你当前使用的默认multi_match是基于分词的精确词匹配,如果你用的是标准分词器,类似hoffman这类完整词不会被拆分为包含man的分词,因此无法命中目标结果,有两种常用方案可选:
方案一:临时查询无需修改Mapping(适合小数据量场景)
直接使用通配符匹配,将所有需要查询的字段合并到同一个multi_match配置中,设置匹配类型为wildcard,查询内容补充通配符即可:
{ "query": { "multi_match": { "query": "*man*", "type": "wildcard", "fields": [ "name", "last_name", "email", "billing.name", "billing.last_name", "billing.email" ] } } }
如果仅需要匹配开头为man的内容,将查询值改为man*即可。
方案二:高性能查询(适合大数据量场景,需要提前修改Mapping)
给需要查询的字段配置ngram分词器,会提前把字段内容拆分为固定长度的子串建立索引,查询时直接用默认multi_match就能命中包含子串的结果,性能远高于通配符查询。
示例Mapping配置参考:
{ "settings": { "analysis": { "analyzer": { "ngram_analyzer": { "tokenizer": "ngram_tokenizer" } }, "tokenizer": { "ngram_tokenizer": { "type": "ngram", "min_gram": 2, "max_gram": 10 } } } }, "mappings": { "properties": { "name": { "type": "text", "analyzer": "ngram_analyzer" }, "last_name": { "type": "text", "analyzer": "ngram_analyzer" }, // 其他需要查询的字段按相同规则配置分词器即可 } } }
配置完成后重建索引,再使用你最初编写的multi_match语句即可命中hoffman这类包含man的结果。
内容的提问来源于stack exchange,提问作者Mike
相关产品推荐
相关产品推荐

