Lucene 3.0.0 的TokenStream与Analyzer

Lucene 3.0.0 的TokenStream与Analyzer如果你看的Lucene相关的书是很老版本的,比如说2.4或者更早,那么对于这个版本中的Analyzer可能就不那么容易接受了,我也是看的<lucene分析与应用>这本书,比较古老的版本.今天读了一下源代码,大概说说心得,我从SimpleAnalyzer说起.SimpleAnalyzer的作用就是把一段字符串中除了符号和非文字的内容作为分…

大家好,又见面了,我是你们的朋友全栈君。

     如果你看的Lucene相关的书是很老版本的, 比如说2.4或者更早, 那么对于这个版本中的Analyzer可能就不那么容易接受了, 我也是看的<lucene分析与应用>这本书, 比较古老的版本.

     今天读了一下源代码, 大概说说心得, 我从SimpleAnalyzer说起.

     SimpleAnalyzer的作用就是把一段字符串中除了符号和非文字的内容作为分隔, 把句子分成很多的单词. 对于中文也可以用来剔除标点符号

public TokenStream tokenStream(String fieldName, Reader reader) {
    
    
  return new LowerCaseTokenizer(reader);
}

     SimpleAnalyzer的TokenStream就是调用了LowerCaseTokenizer的构造函数. LowerCaseTokenizer继承自CharTokenizer. 首先来看看CharTokenizer的构造函数吧:

public CharTokenizer(Reader input) {
    
    
  super(input);
  offsetAtt = addAttribute(OffsetAttribute.class);
  termAtt = addAttribute(TermAttribute.class);
}

     除了调用基类的构造函数外(继承自Tokenizer), 另外还有下面两个与Attribute相关的语句, Attribute是Lucene新增的内容(具体是不是3.0新增的就不清楚了), 作用是可以在TokenStream中加入一些用户需要的内容, 比如说单词的词性, 文字等等内容, 这些东西是可以用户定义的, 提供了更多的耦合性, 怎么访问这些内容我上一篇日志也是有说的.

     下面我把CharTokenizer的incrementToken()函数的代码贴出来分析一下

public final boolean incrementToken() throws IOException {
    
    
  clearAttributes();
  int length = 0;
  int start = bufferIndex;
  char[] buffer = termAtt.termBuffer();
  while (true) {
    
    
 
    if (bufferIndex >= dataLen) {
    
    
      offset += dataLen;
      dataLen = input.read(ioBuffer);
      if (dataLen == -1) {
    
    
        dataLen = 0;                            // so next offset += dataLen won't decrement offset
        if (length > 0)
          break;
        else
          return false;
      }
      bufferIndex = 0;
    }
 
    final char c = ioBuffer[bufferIndex++];
 
    if (isTokenChar(c)) {               // if it's a token char
 
      if (length == 0)                 // start of token
        start = offset + bufferIndex - 1;
      else if (length == buffer.length)
        buffer = termAtt.resizeTermBuffer(1+length);
 
      buffer[length++] = normalize(c); // buffer it, normalized
 
      if (length == MAX_WORD_LEN)      // buffer overflow!
        break;
 
    } else if (length > 0)             // at non-Letter w/ chars
      break;                           // return 'em
  }
 
  termAtt.setTermLength(length);
  offsetAtt.setOffset(correctOffset(start), correctOffset(start+length));
  return true;
}

     在一个Tokenizer里面将保留这多个Attribute的实例, 这些实例是循环利用的, 每新得到一个单词, 就改写一下他们的内容,

1)

if (bufferIndex >= dataLen) {
    
    
  offset += dataLen;
  dataLen = input.read(ioBuffer);
  if (dataLen == -1) {
    
    
    dataLen = 0;                            // so next offset += dataLen won't decrement offset
    if (length > 0)
      break;
    else
      return false;
  }
  bufferIndex = 0;
}

这段代码是初始化的内容, 得到整个字符串的长度, ioBuffer就是这个字符串

2)

final char c = ioBuffer[bufferIndex++];
 
if (isTokenChar(c)) {               // if it's a token char
 
  if (length == 0)                 // start of token
    start = offset + bufferIndex - 1;
  else if (length == buffer.length)
    buffer = termAtt.resizeTermBuffer(1+length);
 
  buffer[length++] = normalize(c); // buffer it, normalized
 
  if (length == MAX_WORD_LEN)      // buffer overflow!
    break;
 
} else if (length > 0)             // at non-Letter w/ chars
  break;                           // return 'em

这段代码是不停的读取下一个字符, 看看是符号还是合法的字符.

3)

termAtt.setTermLength(length);
offsetAtt.setOffset(correctOffset(start), correctOffset(start+length));
return true;

最后把单词的termAtt和offsetAtt赋值, 返回

转载于:https://www.cnblogs.com/LeftNotEasy/archive/2010/01/17/1650139.html

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/163122.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • c++语言入门教程–16c++ 中的 String 类

    c++语言入门教程–16c++ 中的 String 类

  • 区块链与联邦学习的研究

    区块链与联邦学习的研究本文分别介绍了区块链与联邦学习的研究现状、架构和运行原理、主要技术及局限性,并针对区块链与联邦学习所存在的问题,通过分析区块链与联邦学习各自的特点,探讨了如何将区块链与联邦学习进行融合互补,介绍了两种融合模型及其应用场景。1区块链概述1.1 区块链的研究现状2008年10月,化名为“中本聪”的学者在密码学论坛上公开了《比特币:一种点对点的电子现金系统》一文[1],提出了利用PoW和时间戳机制构造交易区块的链式结构,剔除了可信第三方,实现了去中心化的匿名支付。比特币于2009年1月上线并发布创世块,.

  • 雷军反击董明珠:感觉董总好像认输了似的

    雷军反击董明珠:感觉董总好像认输了似的

  • UFT如何在谷歌浏览器上实现录制

    UFT如何在谷歌浏览器上实现录制https://user.qzone.qq.com/305132437/blog/1395738617?t=0.748526355385565https://user.qzone.qq.com/305132437/blog/14097396271.UFT安装目录\bin\Chrome,找到Agent.crx,复制2.拷贝到win7系统啊C:\Users\用户\AppData\Local\…

  • linux里chmod_vim命令下一页

    linux里chmod_vim命令下一页linux中chmod命令的使用方法发布时间:2020-06-2417:05:24来源:亿速云阅读:79作者:元一这篇文章运用简单易懂的例子给大家介绍linux中chmod命令的使用方法,代码非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。chmod介绍:linux中可以使用命令chmod来为文件或目录赋予权限。Linux/Unix的档案存取权限分为三级:档案拥有者、群组、其…

    2022年10月26日
  • 设计模式 | 适配器模式及典型应用

    设计模式 | 适配器模式及典型应用适配器模式适配器模式(AdapterPattern):将一个接口转换成客户希望的另一个接口,使接口不兼容的那些类可以一起工作,其别名为包装器(Wrapper)。适配器模式既可以作为类结构型模式,也可以作为对象结构型模式。在适配器模式中,我们通过增加一个新的适配器类来解决接口不兼容的问题,使得原本没有任何关系的类可以协同工作。根据适配器类与适配者类的关系不同,适配器模式可分为对象适配器和类适…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号