如何在Elasticsearch中搜索关键词food匹配到food2u这类内容
问题原因
你当前使用的ES默认standard分词器处理text类型字段时,仅会按照空格、标点等非字母数字符号拆分词汇,food2u会被作为完整的不可拆分的词条存入倒排索引。你搜索food时分词结果只有food,和完整的food2u词条无法匹配,因此只能返回空格分隔的包含独立food词汇的结果。
解决方案
方案1:无需调整Mapping的临时查询方案
适合小数据量临时测试使用,直接改用wildcard查询即可匹配到food开头的内容,查询语句如下:
GET api/_search { "query": { "wildcard": { "Name": { "value": "food*" } } }, "_source": { "includes": ["Name"] } }
如果需要匹配food出现在任意位置的内容(如myfood2u),可将通配符规则修改为*food*,但查询性能会进一步下降。
方案2:生产环境最优方案(调整分词规则)
通过自定义ngram分词器,在索引构建阶段就将词汇拆分为多段子词条存入倒排索引,匹配效率远高于通配符查询,操作步骤如下:
- 重建索引,配置自定义ngram分词器:
PUT api { "settings": { "analysis": { "analyzer": { "ngram_analyzer": { "tokenizer": "ngram_tokenizer" } }, "tokenizer": { "ngram_tokenizer": { "type": "ngram", "min_gram": 2, "max_gram": 10, "token_chars": ["letter", "digit"] } } } }, "mappings": { "properties": { "Name": { "type": "text", "analyzer": "ngram_analyzer", "search_analyzer": "standard" } } } }
- 重新导入所有数据后,你原来的
match查询就可以直接匹配到food2u这类结果。
补充说明:如果仅需要匹配关键词在词首的场景,可将分词器类型替换为
edge_ngram,能减少索引存储空间占用,进一步提升查询效率。
内容的提问来源于stack exchange,提问作者Pan
相关产品推荐
相关产品推荐

