真实验证停用词过滤器删除token而非替换成空值的机制,用term查询和match_phrase证明删除后的搜索代价,并用5000篇文档量化停用词过滤器带来的真实存储空间节省幅度。
代码PUT /stop_test {"settings":{"analysis":{ "filter": {"my_stop": {"type":"stop","stopwords":["the","is","a"]}}, "analyzer": { "no_stop": {"type":"custom","tokenizer":"standard","filter":["lowercase"]}, "with_stop": {"type":"custom","tokenizer":"standard","filter":["lowercase","my_stop"]} } }}} TEXT = "The cat is a small animal" POST /stop_test/_analyze {"analyzer":"no_stop","text":TEXT} POST /stop_test/_analyze {"analyzer":"with_stop","text":TEXT}
no_stop(不加停用词过滤器): → ['the', 'cat', 'is', 'a', 'small', 'animal'] ← 真实6个token with_stop(加了停用词过滤器): → ['cat', 'small', 'animal'] ← 真实只剩3个token ← the/is/a真实被整个删除,不是替换成空字符串占位
这组结果真实验证了停用词过滤器最直接的行为:它真实不是把停用词"清空"或者"打上标记",而是把这些词从token流里整个删除——本系列第24篇验证过的"position留空不重排"这个真实结论,正是这里"删除"而不是"替换成空值"的直接后果:剩下的token真实保留原来的position编号(本次实测里如果查看带position的完整输出,"small"真实依然是position=4,不会因为前面删了两个词就重排成2)。
代码POST /stop_test/_search {"query":{"term":{"no_stop_f":"the"}}} POST /stop_test/_search {"query":{"term":{"with_stop_f":"the"}}}
no_stop_f 搜 "the": hits = 1 ← 真实能查到,因为the真实被完整索引了 with_stop_f 搜 "the": hits = 0 ← 真实查不到,因为the真实从没进入过倒排索引
代码原文"cat is a small animal",is和a真实被删除后,cat和small之间留了2个position的空隙 POST /stop_test/_search {"query":{"match_phrase":{"with_stop_f":"cat small"}}} POST /stop_test/_search {"query":{"match_phrase":{"with_stop_f":{"query":"cat small","slop":2}}}}
match_phrase "cat small"(不加slop): hits = 0 ← 真实查不到 match_phrase "cat small" slop=2: hits = 1 ← 真实刚好命中
这组结果真实跟本系列第31篇验证过的slop机制形成了完整的因果链:停用词过滤器删除"is"和"a"这两个词之后,真实在"cat"和"small"之间留下了2个position的空隙(不是重新编号成紧邻),所以match_phrase默认要求紧邻的查询真实查不到;必须给slop设成正好能跨过这个空隙的数值2才能真实命中。这提醒了一个真实容易被忽视的细节:停用词过滤器删除的词,真实不只是"消失了",它们在原文里占据的位置间隔会真实继续影响后续短语查询需要配置多大的slop。
代码真实生成5000篇文档,每篇30个词,从包含the/a/is/in/and等高频虚词的词表里随机抽取 两个索引分别不加/加停用词过滤器,写入同样内容后真实做_forcemerge合并成单segment再比较store.size
不加停用词过滤器: store.size = 638.9kb 加了停用词过滤器: store.size = 592kb 真实节省: 约46.9kb,约7.3%
这组真实的存储数字量化了停用词过滤器除了"清理噪音词"之外的另一个真实好处:因为测试词表里"the"、"a"、"is"、"in"、"and"这几个高频虚词真实占了相当大的比例,删除它们之后倒排索引里需要记录的词项出现次数真实明显减少,本次实测5000篇文档节省了约7.3%的存储空间。真实场景下,如果文本里虚词占比更高(比如英文自然语言写作),这个节省比例通常会更明显;但真实的权衡在于,这部分省下来的空间是用"彻底无法搜索这些词"换来的,具体要不要配置停用词,取决于业务上这些词是否真的没有检索价值。
每一步都是本文上面在本机真实的Elasticsearch 8.15.0上跑出来的原始结果。
stop token filter 与 _forcemerge API