Elasticsearch significant_text聚合如何实现停用词过滤
核心原因
你之前配置停用词分析器不生效、gnd配置无效的原因非常明确:
significant_text聚合直接读取字段写入时的预分词结果做统计,不会在查询阶段临时套用你修改的分析器逻辑。如果配置停用词过滤器后没有重建索引、重刷存量数据,旧分词结果里的停用词会一直保留,自然过滤不掉。- gnd是显著性打分算法,只负责调整词项的权重排序,本身不具备停用词剔除能力,对过滤无意义词没有任何作用。
解决方案
方案1:索引层面配置(长期最优解)
这是最彻底的解决方式,步骤如下:
- 新建索引,为
text字段绑定带停用词过滤的自定义分析器,配置示例:
PUT /feed_new { "settings": { "analysis": { "filter": { "en_stop_filter": { "type": "stop", "stopwords": "_english_" } }, "analyzer": { "en_stop_analyzer": { "tokenizer": "standard", "filter": [ "lowercase", "en_stop_filter" ] } } } }, "mappings": { "properties": { "text": { "type": "text", "analyzer": "en_stop_analyzer", "fielddata": true }, // sentiment、level、asset_id等其余原有字段保持原mapping配置即可 } } }
- 用
reindex接口将旧feed索引的全量数据迁移到新索引,切换别名指向新索引后,再运行你原来的significant_text聚合查询,就不会再返回无意义停用词。
注意:如果配置完分析器不重建索引、不重写数据,存量文档的分词结果不会更新,这是绝大多数人配置停用词不生效的核心原因。如果有自定义停用词需求,直接在stop过滤器的stopwords数组里追加自定义词汇即可。
方案2:查询层面过滤(临时快速生效)
如果暂时不具备重建索引的条件,可以直接在significant_text聚合中配置exclude参数,在分桶阶段直接剔除指定停用词,不需要修改索引配置,即时生效。
- 你只需要把原有聚合里的
trending_topics配置修改为如下形式即可:
"trending_topics": { "significant_text": { "field": "text", "filter_duplicate_text": true, "exclude": ["the", "a", "an", "they", "them", "their", "is", "are", "was", "were", "of", "to", "in", "on", "at", "for", "with", "as", "it", "its", "this", "that", "and", "or", "but", "if", "so"] } }
- 可以根据实际返回结果里出现的无意义词汇,随时往exclude数组里追加内容。该方案缺点是需要手动维护停用词表,适合临时统计场景使用。
补充说明
不要尝试靠调整min_doc_count参数过滤停用词:
- 这个参数是按词项出现的文档数阈值过滤,无法区分通用停用词和业务层面的高频有效词,调大阈值会把有统计价值的高频词一并过滤掉。
内容的提问来源于stack exchange,提问作者hanilosaurus
相关产品推荐
相关产品推荐

