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.

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

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

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

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

(0)


相关推荐

  • Flink的sink实战之四:自定义

    Flink的sink实战之四:自定义

    2020年11月19日
  • 创建外部用户_外部表

    创建外部用户_外部表

  • 区块链P2P网络协议演进过程[通俗易懂]

    区块链P2P网络协议演进过程[通俗易懂]区块链是以加密机制、储存机制、共识机制等多种技术组成的分布式系统,可以在无中心服务器的情况下实现相互信任的点对点交易功能。区块链最大的特点是去中心化和分布式,区块链共识机制使得参与节点共同为系统提供服务,实现中心化系统中类似金融中介机构的功能。共识机制是网络大部分节点在约定时间段内对交易状态达成相同的确认,其中共识性通过工作量证明(POW)、权益证明(POS)、实用拜占庭容错(PBFT)等多种共识算法实现。而一致性则要求大部分节点在约定时间段内保持数据内容一致,从而利用共识算法实现共识。传统中心化网络系统需

  • ORA12154和TNS03505监听错误的解决方法「建议收藏」

    ORA12154和TNS03505监听错误的解决方法「建议收藏」原ORA-12154和TNS-03505监听错误的解决方法https://blog.csdn.net/tianlesoftware/article/details/5716028版权声明:https://blog.csdn.net/tianlesoftware/article/details/5716028之前在一台测试机上装了GridControl,今天在这台机器上添加了一个监听,…

  • Tomcat部署WAR包访问不带项目名的方式

    Tomcat部署WAR包访问不带项目名的方式1、将项目打成WAR包放在Tomcat的webapps目录下2、在Tomcat的安装目录的conf下找到server.xml的文件,如:D:\apache-tomcat-9.0.8\conf\server.xml3、在Host标签里边添加<Hostname=”localhost”appBase=”webapps”unpackWARs=”true”…

  • linux目录结构详解_简述linux系统中的目录结构

    linux目录结构详解_简述linux系统中的目录结构前言平常linux系统用的也不少,那么linux下的每个目录都是用来干什么的,小伙伴们有仔细研究过吗?让我们来了解下吧Linux系统目录结构登录系统后,在当前命令窗口下输入命令:[root@

发表回复

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

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