lucene fieldNorm lengthNorm未真正计算文档长度

Lucene默认的相似度计算中,lengthNorm方法并未实际用于计算文档长度。源码分析表明,文档长度是通过1.0除以Math.sqrt(numTerms)来简单估算的。若需按标准文档长度或其他特定方式计算,需自定义Similarity类。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

lucene 相似度默认实现:计算文档长度时没有调用lengthNorm方法文档长度。

public float lengthNorm(String fieldName, int numTerms) {
return (float) (1.0 / Math.sqrt(numTerms));
}

源码剖析:

TermQuery类下的方法:

public Explanation explain(IndexReader reader, int doc) throws IOException {
...
//从索引中读取byte[]值,在创建索引的时候已经写入了
 byte[] fieldNorms = reader.norms(field);
      float fieldNorm =
        fieldNorms!=null ? Similarity.decodeNorm(fieldNorms[doc]) : 1.0f;
...
}
//decodeNorm方法:将byte解码成float值,在搜索查询时从索引中的byte解码城float
 public static float decodeNorm(byte b) {
    return NORM_TABLE[b & 0xFF];  // & 0xFF maps negative bytes to positive above 127
  }
//NORM_TABLE具体为:
 private static final float[] NORM_TABLE = new float[256];
//此处NORM_TABLE范围固定,因此没有调用lengthNorm计算文档长度,文档长短不一样可能得分一样 
 static {
    for (int i = 0; i < 256; i++)
      NORM_TABLE[i] = SmallFloat.byte315ToFloat((byte)i);
  }

//编码float值,在创建索引时byte 写入索引中
  public static byte encodeNorm(float f) {
    return SmallFloat.floatToByte315(f);
}
SmallFloat类下的两个方法:
 //
  // Some specializations of the generic functions follow.
  // The generic functions are just as fast with current (1.5)
  // -server JVMs, but still slower with client JVMs.
  //
  /** floatToByte(b, mantissaBits=3, zeroExponent=15)
   * <br>smallest non-zero value = 5.820766E-10
   * <br>largest value = 7.5161928E9
   * <br>epsilon = 0.125
   */
  public static byte floatToByte315(float f) {
    int bits = Float.floatToRawIntBits(f);
    int smallfloat = bits >> (24-3);
    if (smallfloat < (63-15)<<3) {
      return (bits<=0) ? (byte)0 : (byte)1;
    }
    if (smallfloat >= ((63-15)<<3) + 0x100) {
      return -1;
    }
    return (byte)(smallfloat - ((63-15)<<3));
 }

  /** byteToFloat(b, mantissaBits=3, zeroExponent=15) */
  public static float byte315ToFloat(byte b) {
    // on Java1.5 & 1.6 JVMs, prebuilding a decoding array and doing a lookup
    // is only a little bit faster (anywhere from 0% to 7%)
    if (b == 0) return 0.0f;
    int bits = (b&0xff) << (24-3);
    bits += (63-15) << 24;
    return Float.intBitsToFloat(bits);
  }


因此如果按照标准计算文档长度或其他需求等要自已实现Similarity。


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值