大家好,又见面了,我是你们的朋友全栈君。
如果你看的Lucene相关的书是很老版本的, 比如说2.4或者更早, 那么对于这个版本中的Analyzer可能就不那么容易接受了, 我也是看的<lucene分析与应用>这本书, 比较古老的版本.
今天读了一下源代码, 大概说说心得, 我从SimpleAnalyzer说起.
SimpleAnalyzer的作用就是把一段字符串中除了符号和非文字的内容作为分隔, 把句子分成很多的单词. 对于中文也可以用来剔除标点符号
代码语言:javascript复制public TokenStream tokenStream(String fieldName, Reader reader) {代码语言:javascript复制 return new LowerCaseTokenizer(reader);代码语言:javascript复制}SimpleAnalyzer的TokenStream就是调用了LowerCaseTokenizer的构造函数. LowerCaseTokenizer继承自CharTokenizer. 首先来看看CharTokenizer的构造函数吧:
代码语言:javascript复制public CharTokenizer(Reader input) {代码语言:javascript复制 super(input);代码语言:javascript复制 offsetAtt = addAttribute(OffsetAttribute.class);代码语言:javascript复制 termAtt = addAttribute(TermAttribute.class);代码语言:javascript复制}除了调用基类的构造函数外(继承自Tokenizer), 另外还有下面两个与Attribute相关的语句, Attribute是Lucene新增的内容(具体是不是3.0新增的就不清楚了), 作用是可以在TokenStream中加入一些用户需要的内容, 比如说单词的词性, 文字等等内容, 这些东西是可以用户定义的, 提供了更多的耦合性, 怎么访问这些内容我上一篇日志也是有说的.
下面我把CharTokenizer的incrementToken()函数的代码贴出来分析一下
代码语言:javascript复制public final boolean incrementToken() throws IOException {代码语言:javascript复制 clearAttributes();代码语言:javascript复制 int length = 0;代码语言:javascript复制 int start = bufferIndex;代码语言:javascript复制 char[] buffer = termAtt.termBuffer();代码语言:javascript复制 while (true) {代码语言:javascript复制代码语言:javascript复制 if (bufferIndex >= dataLen) {代码语言:javascript复制 offset = dataLen;代码语言:javascript复制 dataLen = input.read(ioBuffer);代码语言:javascript复制 if (dataLen == -1) {代码语言:javascript复制 dataLen = 0; // so next offset = dataLen won't decrement offset代码语言:javascript复制 if (length > 0)代码语言:javascript复制 break;代码语言:javascript复制 else代码语言:javascript复制 return false;代码语言:javascript复制 }代码语言:javascript复制 bufferIndex = 0;代码语言:javascript复制 }代码语言:javascript复制代码语言:javascript复制 final char c = ioBuffer[bufferIndex ];代码语言:javascript复制代码语言:javascript复制 if (isTokenChar(c)) { // if it's a token char代码语言:javascript复制代码语言:javascript复制 if (length == 0) // start of token代码语言:javascript复制 start = offset bufferIndex - 1;代码语言:javascript复制 else if (length == buffer.length)代码语言:javascript复制 buffer = termAtt.resizeTermBuffer(1 length);代码语言:javascript复制代码语言:javascript复制 buffer[length ] = normalize(c); // buffer it, normalized代码语言:javascript复制代码语言:javascript复制 if (length == MAX_WORD_LEN) // buffer overflow!代码语言:javascript复制 break;代码语言:javascript复制代码语言:javascript复制 } else if (length > 0) // at non-Letter w/ chars代码语言:javascript复制 break; // return 'em代码语言:javascript复制 }代码语言:javascript复制代码语言:javascript复制 termAtt.setTermLength(length);代码语言:javascript复制 offsetAtt.setOffset(correctOffset(start), correctOffset(start length));代码语言:javascript复制 return true;代码语言:javascript复制}在一个Tokenizer里面将保留这多个Attribute的实例, 这些实例是循环利用的, 每新得到一个单词, 就改写一下他们的内容,
1)
代码语言:javascript复制if (bufferIndex >= dataLen) {代码语言:javascript复制 offset = dataLen;代码语言:javascript复制 dataLen = input.read(ioBuffer);代码语言:javascript复制 if (dataLen == -1) {代码语言:javascript复制 dataLen = 0; // so next offset = dataLen won't decrement offset代码语言:javascript复制 if (length > 0)代码语言:javascript复制 break;代码语言:javascript复制 else代码语言:javascript复制 return false;代码语言:javascript复制 }代码语言:javascript复制 bufferIndex = 0;代码语言:javascript复制}这段代码是初始化的内容, 得到整个字符串的长度, ioBuffer就是这个字符串
2)
代码语言:javascript复制final char c = ioBuffer[bufferIndex ];代码语言:javascript复制代码语言:javascript复制if (isTokenChar(c)) { // if it's a token char代码语言:javascript复制代码语言:javascript复制 if (length == 0) // start of token代码语言:javascript复制 start = offset bufferIndex - 1;代码语言:javascript复制 else if (length == buffer.length)代码语言:javascript复制 buffer = termAtt.resizeTermBuffer(1 length);代码语言:javascript复制代码语言:javascript复制 buffer[length ] = normalize(c); // buffer it, normalized代码语言:javascript复制代码语言:javascript复制 if (length == MAX_WORD_LEN) // buffer overflow!代码语言:javascript复制 break;代码语言:javascript复制代码语言:javascript复制} else if (length > 0) // at non-Letter w/ chars代码语言:javascript复制 break; // return 'em这段代码是不停的读取下一个字符, 看看是符号还是合法的字符.
3)
代码语言:javascript复制termAtt.setTermLength(length);代码语言:javascript复制offsetAtt.setOffset(correctOffset(start), correctOffset(start length));代码语言:javascript复制return true;最后把单词的termAtt和offsetAtt赋值, 返回
转载于:https://www.cnblogs.com/LeftNotEasy/archive/2010/01/17/1650139.html
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/163122.html原文链接:https://javaforall.cn


