大家好,又见面了,我是你们的朋友全栈君。
如果你看的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