Lucene源码解析–TokenStream和AttributeSource

Lucene源码解析–TokenStream和AttributeSource转 http://blog.itpub.net/28624388/viewspace-765691/一:Lucene的概况<style./*Style.Definitions*/table.MsoNormalTable{mso-style-name:普通表格;mso-tstyle-rowband-size:0;mso-tstyle-colband-size:0;…

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

转 http://blog.itpub.net/28624388/viewspace-765691/
一:Lucene 的概况
<style. /* Style. Definitions */ table.MsoNormalTable {mso-style-name:普通表格; mso-tstyle-rowband-size:0; mso-tstyle-colband-size:0; mso-style-noshow:yes; mso-style-priority:99; mso-style-qformat:yes; mso-style-parent:””; mso-padding-alt:0cm 5.4pt 0cm 5.4pt; mso-para-margin:0cm; mso-para-margin-bottom:.0001pt; mso-pagination:widow-orphan; font-size:10.5pt; mso-bidi-font-size:11.0pt; font-family:”Calibri”,”sans-serif”; mso-ascii-font-family:Calibri; mso-ascii-theme-font:minor-latin; mso-hansi-font-family:Calibri; mso-hansi-theme-font:minor-latin; mso-bidi-font-family:”Times New Roman”; mso-bidi-theme-font:minor-bidi; mso-font-kerning:1.0pt;} </style.

Lucene源码解析--TokenStream和AttributeSource

Normal 0 7.8 磅 0 2 false false false EN-US ZH-CN X-NONE</w:LidThemeComplexScript. MicrosoftInternetExplorer4

 

  • Luceneanalysis模块主要负责词法分析及语言处理而形成Term
  • Luceneindex模块主要负责索引的创建,里面有IndexWriter
  • Lucenestore模块主要负责索引的读写。
  • LuceneQueryParser主要负责语法分析。 
  • Lucenesearch模块主要负责对索引的搜索。
  • Lucenesimilarity模块主要负责对相关性打分的实现。

Lucene包结构功能表

包名

功能

org.apache.lucene.analysis

语言分析器,主要用于的切词,支持中文主要是扩展此类

org.apache.lucene.document

索引存储时的文档结构管理,类似于关系型数据库的表结构

org.apache.lucene.index

索引管理,包括索引建立、删除等

org.apache.lucene.queryParser

查询分析器,实现查询关键词间的运算,如与、或、非等

org.apache.lucene.search

检索管理,根据查询条件,检索得到结果

org.apache.lucene.store

数据存储管理,主要包括一些底层的I/O操作

org.apache.lucene.util

一些公用类


二:TokenStream和AttributeStream

Normal 0 7.8 磅 0 2 false false false EN-US ZH-CN X-NONE</w:LidThemeComplexScript. MicrosoftInternetExplorer4

Analyzer通过对文本的分析来建立TokenStreams(分词数据流)TokenStream是由一个个Token(分词组成的数据流)。所以说Analyzer就代表着一个从文本数据中抽取索引词(Term)的一种策略。为了定义具体完成哪些分析工作,Analyzer的子类必须实行自己的createCompontents方法。这里也是我们进行中文扩展的主要切入口。

 

Normal 0 7.8 磅 0 2 false false false EN-US ZH-CN X-NONE</w:LidThemeComplexScript. MicrosoftInternetExplorer4

<style. /* Style. Definitions */ table.MsoNormalTable {mso-style-name:普通表格; mso-tstyle-rowband-size:0; mso-tstyle-colband-size:0; mso-style-noshow:yes; mso-style-priority:99; mso-style-qformat:yes; mso-style-parent:””; mso-padding-alt:0cm 5.4pt 0cm 5.4pt; mso-para-margin:0cm; mso-para-margin-bottom:.0001pt; mso-pagination:widow-orphan; font-size:10.5pt; mso-bidi-font-size:11.0pt; font-family:”Calibri”,”sans-serif”; mso-ascii-font-family:Calibri; mso-ascii-theme-font:minor-latin; mso-hansi-font-family:Calibri; mso-hansi-theme-font:minor-latin; mso-bidi-font-family:”Times New Roman”; mso-bidi-theme-font:minor-bidi; mso-font-kerning:1.0pt;} </style.

TokenStream即是从Document的域(field)中或者查询条件中抽取一个个分词而组成的一个数据流。TokenSteam中是一个个的分词,而每个分词又是由一个个的属性(Attribute)组成。对于所有的分词来说,每个属性只有一个实例。这些属性都保存在AttributeSource中,而AttributeSource正是TokenStream的父类。

Normal 0 7.8 磅 0 2 false false false EN-US ZH-CN X-NONE</w:LidThemeComplexScript. MicrosoftInternetExplorer4

 

<style. /* Style. Definitions */ table.MsoNormalTable {mso-style-name:普通表格; mso-tstyle-rowband-size:0; mso-tstyle-colband-size:0; mso-style-noshow:yes; mso-style-priority:99; mso-style-qformat:yes; mso-style-parent:””; mso-padding-alt:0cm 5.4pt 0cm 5.4pt; mso-para-margin:0cm; mso-para-margin-bottom:.0001pt; mso-pagination:widow-orphan; font-size:10.5pt; mso-bidi-font-size:11.0pt; font-family:”Calibri”,”sans-serif”; mso-ascii-font-family:Calibri; mso-ascii-theme-font:minor-latin; mso-hansi-font-family:Calibri; mso-hansi-theme-font:minor-latin; mso-bidi-font-family:”Times New Roman”; mso-bidi-theme-font:minor-bidi; mso-font-kerning:1.0pt;} </style.

TokenStream的工作流程:

1.实例化TokenStream, 添加属性到AttributeSource,或从AttributeSource中获取属性.

2.调用reset()方法,设置stream的初始状态

3.调用increamStoken()方法,来获取下一个分词。这个方法会被docuemnt中的每一个分词调用。所以一个有效的实现对于好的性能来说是至关重要的。

4.调用end()方法来完成一些收尾工作

5.调用close()方法来释放stream关联的一些资源。

 

Normal 0 7.8 磅 0 2 false false false EN-US ZH-CN X-NONE</w:LidThemeComplexScript. MicrosoftInternetExplorer4

 

<style. /* Style. Definitions */ table.MsoNormalTable {mso-style-name:普通表格; mso-tstyle-rowband-size:0; mso-tstyle-colband-size:0; mso-style-noshow:yes; mso-style-priority:99; mso-style-qformat:yes; mso-style-parent:””; mso-padding-alt:0cm 5.4pt 0cm 5.4pt; mso-para-margin:0cm; mso-para-margin-bottom:.0001pt; mso-pagination:widow-orphan; font-size:10.5pt; mso-bidi-font-size:11.0pt; font-family:”Calibri”,”sans-serif”; mso-ascii-font-family:Calibri; mso-ascii-theme-font:minor-latin; mso-hansi-font-family:Calibri; mso-hansi-theme-font:minor-latin; mso-bidi-font-family:”Times New Roman”; mso-bidi-theme-font:minor-bidi; mso-font-kerning:1.0pt;} </style.

AttributeSource:

一个AttributeSource中包含着一个由不同AttributeImpl组成的列表,以及添加和获取它们的一些方法。

在同一个AttributeSource实例中 每个属性只有一个单实例。AttributeSource通过AttributeFactory来创建AttributeImpl的实例。通过State来标示每个AttributeImpl的状态。

 private final Map<Class<? extends Attribute>, AttributeImpl> attributes; 

private final Map<Class<? extends AttributeImpl>, AttributeImpl> attributeImpls;

上述两个成员保存了两种映射关系,

1.AttributeImpl实例对应实现的所有Attribute接口,都可以映射到该 AttributeImpl实例;

2.AttributeImpl实例对应实现的所有子类对该 AttributeImpl实例的映射。

设计这两个映射关系的目的是在该AttributeSource实例中对每个AttributeAttributeImpl保证只有一个AttributeImpl实例,换句话说,当用具体Attribute或者具体AttributeImpl获取其对象实例时,不会每次都新建实例,而是 首次时建立,其后只返回以前建立的。

三:AttributeImpl类介绍

1.AttributeImpl

一个可以往attributeSource中添加属性的基类,属性通常用来以动态的,线程安全的方式往一个流的数据源中添加数据,如tokenStream。

 

2.CharTermAttributeImpl

保存Token对应的term文本

3.FlagsAttributeImpl

在Tokenizer链中,用以在不同的节点之间传递标识信息。该类同TypeAttribute有着相似的目录但他们之间还是有所不同的,Flags可以用于不同TokenFilter之间分词(Token)信息的加密。

4.TypeAttributeImpl

分词的词汇类型,默认值为“word”

5.KeywordAttributeImpl

该属性用于标识一个分词(token)为关键字。对于TokenStream来说可以用此属性判断分词(Token)是否为关键字来决定是否进行修改,对于TokenFilter来说可以根据分词是否为关键字来进行跳过(skip)处理。

6.OffsetAttributeImpl

Token分词的起始字符,结束字符偏移量

7.PositionIncrementAttribute

它表示tokenStream中的当前token与前一个token在实际的原文本中相隔的词语数量

8.PositionLengthAttributeImpl

Token所占用的位置个数

举例:

原文本:I’m a student. these are apples     

TokenSteam: [1:  I’m ]  [2:a]   [3:student]     [4:these]   [5:are ]   [6:apples]

 

(1) TermAttribute: 表示token的字符串信息。比如”I’m”

(2) TypeAttribute: 表示token的类别信息(在上面讲到)。比如 I’m 就属于<APOSTROPHE>,有撇号的类型

(3) OffsetAttribute:表示token的首字母和尾字母在原文本中的位置。比如 I’m 的位置信息就是(0,3)

(4) PositionIncrementAttribute:这个有点特殊,它表示tokenStream中的当前token与前一个token在实际的原文本中相隔的词语数量。

       比如: 在tokenStream中[2:a] 的前一个token是[1:  I’m ] ,它们在原文本中相隔的词语数是1,则token=”a”的PositionIncrementAttribute值为1。如果token是原文本中的第一个词,则默认值为1。因此上面例子的PositionIncrementAttribute结果就全是1了。

       如果我们使用停用词表来进行过滤之后的话:TokenSteam就会变成: [1:  I’m ]   [2:student]    [3:apples]这时student的PositionIncrementAttribute值就不会再是1,而是与[1:  I’m ]在原文本中相隔词语数量=2。而apples则变成了3。

       那么这个属性有什么用呢,用处很大的。加入我们想搜索一个短语student apples(假如有这个短语)。很显然,用户是要搜索出student apples紧挨着出现的文档。这个时候我们找到了某一篇文档(比如上面例子的字符串)都含有student apples。但是由于apples的PositionIncrementAttribute值是3,说明肯定没有紧挨着。怎么样,用处很大吧。轻而易举的解决了短语搜索的难题哦。

 

四:总结

Normal 0 7.8 磅 0 2 false false false EN-US ZH-CN X-NONE</w:LidThemeComplexScript.

<style. /* Style. Definitions */ table.MsoNormalTable {mso-style-name:普通表格; mso-tstyle-rowband-size:0; mso-tstyle-colband-size:0; mso-style-noshow:yes; mso-style-priority:99; mso-style-qformat:yes; mso-style-parent:””; mso-padding-alt:0cm 5.4pt 0cm 5.4pt; mso-para-margin:0cm; mso-para-margin-bottom:.0001pt; mso-pagination:widow-orphan; font-size:10.5pt; mso-bidi-font-size:11.0pt; font-family:”Calibri”,”sans-serif”; mso-ascii-font-family:Calibri; mso-ascii-theme-font:minor-latin; mso-hansi-font-family:Calibri; mso-hansi-theme-font:minor-latin; mso-bidi-font-family:”Times New Roman”; mso-bidi-theme-font:minor-bidi; mso-font-kerning:1.0pt;} </style.

TokenStream的作用是从给入的文本中不断解析出Token,具体的做法是TokenStream有方法incrementToken,每次调用 将产生待分析文本的下一个Token,其实incrementToken做的事情就是填充用户所关心的若干属性,通过这些属性来反馈分析结果,因此自然而然 的一种想法是TokenStream的派生类中有若干的属性成员,每次调用incrementToken都首先清除上一次的属性信息,然后进行分析并填充 属性,这样做无可厚非,但是请考虑TokenStream流的嵌套,也就是说嵌套的内层流获取的属性将作为外层流的分析的输入,如果使用上述方法实现 TokenStream,则必然嵌套流的每层流都将有自己的属性实例,而层次之间可能会出现同样的属性,也就是说同样的属性实例在流层次中可能会有多个, 这样是没有必要的,也就是说对相同的属性在流层次中只有一个实例就可以满足分析的需求了。

 

当将TokenStream所关心的属性抽象的由AttributeSource来管理时,我们在进行流的嵌套时,根据对AttributeSource的分析可知,外层流定义自己关心的属性,并不需要在构造函数中实例化该属性,而是从AttributeSource中获 取,如果存在的话,则直接返回实例,否则新建,这样在流嵌套式外层流和内存流共享AttributeSource,也就是说当外层流和内层流都关心某个属 性时,内层流首先初始化,此时他将会将该属性注册到AttributeSource中,这样在外层流初始化时将向AttributeSource获取该属 性,从而可以保证在流层次中若干层流都关心的属性只有一份实例。

 

 

 

<style. /* Style. Definitions */ table.MsoNormalTable {mso-style-name:普通表格; mso-tstyle-rowband-size:0; mso-tstyle-colband-size:0; mso-style-noshow:yes; mso-style-priority:99; mso-style-qformat:yes; mso-style-parent:””; mso-padding-alt:0cm 5.4pt 0cm 5.4pt; mso-para-margin:0cm; mso-para-margin-bottom:.0001pt; mso-pagination:widow-orphan; font-size:10.5pt; mso-bidi-font-size:11.0pt; font-family:”Calibri”,”sans-serif”; mso-ascii-font-family:Calibri; mso-ascii-theme-font:minor-latin; mso-hansi-font-family:Calibri; mso-hansi-theme-font:minor-latin; mso-bidi-font-family:”Times New Roman”; mso-bidi-theme-font:minor-bidi; mso-font-kerning:1.0pt;} </style. 

<style. /* Style. Definitions */ table.MsoNormalTable {mso-style-name:普通表格; mso-tstyle-rowband-size:0; mso-tstyle-colband-size:0; mso-style-noshow:yes; mso-style-priority:99; mso-style-qformat:yes; mso-style-parent:””; mso-padding-alt:0cm 5.4pt 0cm 5.4pt; mso-para-margin:0cm; mso-para-margin-bottom:.0001pt; mso-pagination:widow-orphan; font-size:10.5pt; mso-bidi-font-size:11.0pt; font-family:”Calibri”,”sans-serif”; mso-ascii-font-family:Calibri; mso-ascii-theme-font:minor-latin; mso-hansi-font-family:Calibri; mso-hansi-theme-font:minor-latin; mso-bidi-font-family:”Times New Roman”; mso-bidi-theme-font:minor-bidi; mso-font-kerning:1.0pt;} </style.

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

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/163110.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 页面刷新之reload()和refresh()的区别

    页面刷新之reload()和refresh()的区别window.reload()重新加载当前需要的所有内容,也就包括页面和后台的代码,此过程中实际上是从后台重新进行操作;window.refresh()是更新,保存以前的缓存文件內容,再次载入网

    2022年7月1日
    32
  • 图片压缩最优方案

    图片压缩最优方案

    2022年3月1日
    47
  • 2021ArchLinux安装图文教程「建议收藏」

    2021ArchLinux安装图文教程「建议收藏」主要为以下步骤:1.下载ArchLinux安装镜像并制作U盘启动工具2.开机从U盘启动3.进行联网4.编辑镜像站文件(选择一个比较快的中国镜像源)5.开始分区(UEFI+GPT)6.格式化分区,并挂载7.开始安装基本操作系统8.配置基础系统9.引导系统10.用户管理11.网络配置12.安装桌面环境13.安装完后的工作开始:1.下…

    2022年4月25日
    145
  • 线性代数代码实现(六)矩阵除法(C++)

    线性代数代码实现(六)矩阵除法(C++)前言:距离上一篇文章发布已经五天过去了,在这里先给一直等待的伙伴们说声抱歉,因为博主最近的事情很多,只好暂时停更,望大家理解!上一篇文章中,我们介绍了求解逆矩阵的方法,我提到,可逆矩阵可以定义除法。这一篇文章中,讨论一下怎样实现矩阵除法!一、线性代数知识回顾:事实上,矩阵没有“除法”这一概念,我们的“除法”实际上是用以下方式来定义的:设矩阵,,,其中为可逆矩阵,满足以下等式:变换得:如果我们换一种写法,就成了:这样就定义了矩阵除法,我把它称…

    2022年6月18日
    39
  • Web后端开发入门(1)

    Web概述:    在英语中web表示网页的意思,它用于表示Internet主机上供外界访问的资源。Internet上供外界访问的Web资源分为:    1.静态Web资源(如html页面):指web页面中始终不变的数据。    2.动态Web资源:指web页面中供人们浏览的数据是由程序产生的,也就是实时变化的数据。动态Web应用的实现手段:    静态web开发技术有html,常用动态web开发…

    2022年4月4日
    41
  • 局域网连接SQL Server数据库配置

    局域网连接SQL Server数据库配置

    2021年12月30日
    48

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

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