栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 前沿技术 > 大数据 > 大数据系统

Lucene代码分析9

Lucene代码分析9

2021SC@SDUSC

今天继续对Lucene中的Analysis进行分析

阅读的DotLucene版本是1.9.RC1

在索引的时候,添加域的时候,可以指定Analyzer,使其生成TokenStream,也可以直接指定TokenStream:

public Field(String name, TokenStream tokenStream);

下面介绍两个单独使用的TokenStream

1、NumericTokenStream

介绍NumericRangeQuery的时候,在生成NumericField的时候,其会使用NumericTokenStream,其incrementToken如下:

public boolean incrementToken() {

  if (valSize == 0)

    throw new IllegalStateException("call set???Value() before usage");

  if (shift >= valSize)

    return false;

  clearAttributes();

  //虽然NumericTokenStream欲保存数字,然而Lucene的Token只能保存字符串,因而要将数字编码为字符串,然后存入索引。

  final char[] buffer;

  switch (valSize) {

    //首先分配TermBuffer,然后将数字编码为字符串

    case 64:

      buffer = termAtt.resizeTermBuffer(NumericUtils.BUF_SIZE_LONG);

      termAtt.setTermLength(NumericUtils.longToPrefixCoded(value, shift, buffer));

      break;

    case 32:

      buffer = termAtt.resizeTermBuffer(NumericUtils.BUF_SIZE_INT);

      termAtt.setTermLength(NumericUtils.intToPrefixCoded((int) value, shift, buffer));

      break;

    default:

      throw new IllegalArgumentException("valSize must be 32 or 64");

  }

  typeAtt.setType((shift == 0) ? TOKEN_TYPE_FULL_PREC : TOKEN_TYPE_LOWER_PREC);

  posIncrAtt.setPositionIncrement((shift == 0) ? 1 : 0);

  shift += precisionStep;

  return true;

}

public static int intToPrefixCoded(final int val, final int shift, final char[] buffer) {

  if (shift>31 || shift<0)

    throw new IllegalArgumentException("Illegal shift value, must be 0..31");

  int nChars = (31-shift)/7 + 1, len = nChars+1;

  buffer[0] = (char)(SHIFT_START_INT + shift);

  int sortableBits = val ^ 0x80000000;

  sortableBits >>>= shift;

  while (nChars>=1) {

    //int按照每七位组成一个utf-8的编码,并且字符串大小比较的顺序同int大小比较的顺序完全相同。

    buffer[nChars--] = (char)(sortableBits & 0x7f);

    sortableBits >>>= 7;

  }

  return len;

}

2、SingleTokenTokenStream

SingleTokenTokenStream顾名思义就是此TokenStream仅仅包含一个Token,多用于保存一篇文档仅有一个的信息,如id,如time等,这些信息往往被保存在一个特殊的Token(如ID:ID, TIME:TIME)的倒排表的payload中的,这样可以使用跳表来增加访问速度。

所以SingleTokenTokenStream返回的Token则不是id或者time本身,而是特殊的Token,"ID:ID", "TIME:TIME",而是将id的值或者time的值放入payload中。

//索引的时候

int id = 0; //用户自己的文档号

String tokenstring = "ID";

byte[] value = idToBytes(); //将id装换为byte数组

Token token = new Token(tokenstring, 0, tokenstring.length);

token.setPayload(new Payload(value));

SingleTokenTokenStream tokenstream = new SingleTokenTokenStream(token);

document doc = new document();

doc.add(new Field("ID", tokenstream));

……

//当得到Lucene的文档号docid,并不想构造document对象就得到用户的文档号时

TermPositions tp = reader.termPositions("ID:ID");

boolean ret = tp.skipTo(docid);

tp.nextPosition();

int payloadlength = tp.getPayloadLength();

byte[] payloadBuffer = new byte[payloadlength];

tp.getPayload(payloadBuffer, 0);

int id = bytesToID(); //将payloadBuffer转换为用户id

 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/602491.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号