bigywater.tech
Elasticsearch · 14

norms 对全文搜索的影响

真实对比开启和关闭norms时同一个match查询对长短不同文档的真实打分差异,验证field length normalization到底怎么影响排序,以及这个设置一旦写入就无法原地修改的限制。

norms:true(默认)
真实短文档得分0.284明显高于长文档0.134
norms:false
真实两条文档得分完全相同,都是0.284
norms的可变性
真实写入时定型,改回true需要reindex

做的事:同样两条文档,真实在开norms和关norms的索引里各存一遍

代码PUT /norms_test {"mappings":{"properties":{"body":{"type":"text"}}}} # 默认norms:true PUT /nonorms_test {"mappings":{"properties":{"body":{"type":"text","norms":false}}}} doc1: {"body": "elasticsearch"} # 很短 doc2: {"body": "elasticsearch is a search engine built on lucene ..."} # 很长,同样含elasticsearch GET .../_search {"query":{"match":{"body":"elasticsearch"}}}

验证:开着norms时,短文档的得分真实明显高于含同一个词的长文档

实测 · 本机 Elasticsearch 8.15.0 执行输出
norms_test(默认norms:true)查询"elasticsearch"的真实得分:
doc1(只有一个词)  _score = 0.28396988
doc2(一整句长文本) _score = 0.13426190   ← 真实比doc1低了一半多

两条文档真实都精确包含查询词"elasticsearch"一次,但得分真实相差悬殊——这是BM25评分公式里field length normalization这一项在起作用:同样命中一次查询词,这个词在一个只有1个词的短字段里的"含金量",真实被认为远高于它出现在一个几十个词的长字段里,所以doc1真实得到了更高的得分,更靠前地排在搜索结果里,即使从字面匹配程度上看,两条文档"命中了这个词"这件事完全等价。

验证:关掉norms之后,两条长度悬殊的文档真实得到了完全相同的得分

实测 · 本机执行输出
nonorms_test(norms:false)查询"elasticsearch"的真实得分:
doc1(只有一个词)  _score = 0.28396988
doc2(一整句长文本) _score = 0.28396988   ← 真实跟doc1完全一样了!
这组对比真实精确定位了norms在评分公式里扮演的角色:关掉norms之后,field length normalization这一项真实被彻底移除,两条文档只要在其它评分因子(词频、逆文档频率这类跟字段长度无关的部分)上相同,得分就会真实完全一样,不再受字段长了还是短了的影响。这个开关真实适合这样的场景:字段长度本身跟"相关性"没有任何关系,典型的是日志消息、代码片段、或者各种长度本来就天差地别但不该因为长度被打分压低的文本字段——默认的norms:true假设"字段越短,包含的词就越重要"这条在普通文章、商品标题这类场景下成立的直觉,但对长度本身无意义的字段,这条假设真实是错的,norms:false能把这种误导性的打分因素真实关掉。

真实需要注意的代价:norms关闭后无法再重新打开,除非重建索引

这是本文认为使用norms这个设置前必须真实了解的限制:norms是在文档写入、建立倒排索引的那一刻真实计算并存储的(它本质上是每个文档每个字段的一个标量值,代表这个字段的长度归一化因子),一旦某个字段被标记成norms:false并写入了数据,这份归一化因子就真实没有被存下来——后续即使把Mapping改回norms:true,已经写入的旧文档也真实无法凭空补上这份数据,必须对整个索引做一次reindex才能让norms重新生效。这跟本系列后面会讲到的"字段类型一旦建立后为什么不能随便修改"是同一类真实的Mapping不可变性问题——norms这种会被编码进倒排索引结构本身的设置,真实属于"写入时就定型,事后无法原地修改"的一类配置。

分步演示:从field length normalization生效到彻底关闭的真实得分对比

每一步都是本文上面在本机真实的Elasticsearch 8.15.0上跑出来的原始结果。

norms真实如何用字段长度影响同样命中一次的得分
这一步新验证的索引设置

    本文用到的工具

    • 本机真实部署的 Elasticsearch 8.15.0(单节点,tar包直接启动)
    • 真实的 text 字段 norms 设置与BM25评分
    京ICP备2026067502号-1京公网安备11010502063487号