Elasticsearch能否组合trigram与icu_tokenizer实现模糊文本及emoji搜索
方案1:多字段映射(最推荐,性能和灵活性最优)
你可以给同一个文本字段配置多个子字段,分别使用不同的分析器,搜索时同时命中多个子字段即可同时满足两种搜索需求,不需要修改原有分词逻辑,也方便后续单独调优某类搜索的权重。
第一步:定义两个分析器
# 原有trigram分析器,保留用于模糊文本匹配 trigram_analyzer = analyzer( 'trigram_analyzer', tokenizer=tokenizer('trigram', 'ngram', min_gram=3, max_gram=3), filter=['lowercase'], ) # icu分析器,保留用于emoji匹配 icu_analyzer = analyzer( 'icu_analyzer', tokenizer=tokenizer('icu_tokenizer'), filter=['lowercase'], )
第二步:调整字段映射,增加子字段
content_text = Text( analyzer=trigram_analyzer, # 主字段保留原有trigram模糊匹配能力 fields={ 'icu': Text(analyzer=icu_analyzer) # 新增icu子字段专门处理emoji搜索 } )
第三步:搜索时同时匹配两个字段
使用multi_match查询同时命中content_text和content_text.icu即可同时实现模糊文本匹配和emoji搜索,还可以通过boost参数调整两类搜索结果的权重。
方案2:自定义组合分析器
如果不想用多字段结构,可以直接自定义分析器,先用icu分词器处理emoji和基础分词,再通过ngram分词过滤器生成trigram词条,同时满足两种需求:
# 先定义ngram分词过滤器 trigram_filter = token_filter('trigram_filter', 'ngram', min_gram=3, max_gram=3) # 组合后的分析器 document_analyzer = analyzer( 'document_analyzer', tokenizer=tokenizer('icu_tokenizer'), # 先用icu处理emoji和基础分词 filter=['lowercase', trigram_filter] # 再转小写 + 生成trigram词条 )
方案2注意事项
- 若需要支持单个emoji搜索,需将
trigram_filter的min_gram调整为1,但会大幅提升索引体积,同时引入大量无效模糊匹配结果,因此更推荐使用方案1。 - 两种方案都需要先安装Elasticsearch的ICU Analyzer插件,修改分析器配置后需要重建索引才能生效。
内容的提问来源于stack exchange,提问作者Eric
相关产品推荐
相关产品推荐

