通过第四章的学习,可以了解lucene的分析过程是怎样的,并且可以学会如何使用lucene内置分析器,以及自定义分析器。下面是具体总结

1. 分析(Analysis)是什么?

在lucene中,分析就是指:将域(Field)文本转换成最基本的索引表示单元---项(Term)的过程。而项(Term)又是由语汇单元(Token)以及它所属的域名组合而成的。

在索引过程中存在分析(IndexWriter的初始化中需要放入一个Analyzer的实例;并且如果要使Analyzer生效,则需要使用Index.ANALYZED或者Index.ANALYZED_NO_NORMS属性);在利用QueryParser进行搜索的过程中也存在分析(QueryParser的初始化中也需要放入一个Analyzer的实例)。

分析是通过分析器(Analyzer)进行的。Lucene推荐,在索引和搜索期间,使用相同的Analyzer进行处理。

分析器不能做什么?分析器的前提是域已经分好了。因此必须在使用分析器之前,先把文本预先解析并形成域。分析器内不可以创建新的域。

2. Analyzer的作用,就是分析输入的字符文件。其主要的过程如下:

通过调用某个具体Analyzer子类的TokenStream(String fieldName, Reader reader)(reader里面就包含了输入的要解析的文本,fieldname可以为空,即"";但是在不为空时,它起到什么作用呢?),将输入的文本分析成Term。而在TokenStream内部,则可以:1.首先用一个具体的Tokennzer对象从输入的文本创建初始语汇单元序列;2.然后用任意数量(可以是0个)的tokenFilter对象来修改这些语汇单元。最终产生的就是语汇单元流:TokenStream。

3. 语汇单元流是由各个语汇单元组成的。而每个语汇单元的组成,包括了:文本值本身+其他一些元数据。这些都可以理解为该语汇单元的属性,它们是可以通过具体对象实例的API方法得到的。具体为:

TermAttribute ---- 语汇单元对应的文本,通过 .term()方法就可以得到具体文本值

PositionIncrementAttribute --- 本语汇单元相对于前一个语汇单元的位置增量(默认值是1)。通过. getPositionIncrement()可以得到位置增量的值。

OffsetAttriute  --- 语汇单元的起始字符和终止字符的偏移量。其中起始字符偏移量表示的是语汇单元的文本的起始字符在原始文本中的位置,通过.startOffset()得到;而终止字符偏移量则表示语汇单元的文本终止字符的下一个位置。通过.endOffset()得到

TypeAttribute --- 语汇单元类型(默认是 word)。通过.type()得到。

FlagsAttribute --- 自定义标志位 (具体怎么用,尚不清楚)

PayloadAttribute --- 每个语汇单元的byte[]类型有效负载(具体怎么用,尚不清楚)

4. Lucene的内置分析器是需要熟练掌握和运用的。而且书上说,适用范围最广的分析器是StandardAnalyzer

5. 如何创建自己的分析器:一般构建自定义分析器,需要定义Analyzer子类以及自定义TokenFilter;而Tokenizer一般是用现成的。常规套路如下:

A. 自定义一个Analyzer,继承自Analyzer,即书上的例子:

public class MetaphoneReplacementAnalyzer extends Analyzer {

        @Override

        public TokenStream tokenStream(String fieldName, Reader reader)   {

                // TODO Auto-generated method stub

               returnnew MetaphoneReplacementFilter(new LetterTokenizer(reader));

        }

}

B. 自定义TokenFilter(可以是一个或者多个)。在自定义的TokenFilter中,一般就要利用语汇单元的各种属性来对语汇单元进行过滤了。并且还要实现在TokenFilter中唯一要实现的方法:incrementToken()

public class MetaphoneReplacementFilter extends TokenFilter {

        public static final String METAPHONE = "metaphone";

        private Metaphone metaphoner = new Metaphone();

        private TermAttribute termAttr;

       private TypeAttribute typeAttr;

       protected MetaphoneReplacementFilter(TokenStream input) {

                super(input);

                 // TODO Auto-generated constructor stub

                termAttr = addAttribute(TermAttribute.class);

               typeAttr = addAttribute(TypeAttribute.class);

        }

        @Override

         public boolean incrementToken() throws IOException {

                 // TODO Auto-generated method stub

                if(!input.incrementToken()) {

                          return false;

                }

               String encoded;

               encoded = metaphoner.encode(termAttr.term());

               termAttr.setTermBuffer(encoded);

               typeAttr.setType(METAPHONE);

               return true;

        }

}

6. 同时,要知道:网络上有很多现成的分析器实现,可以借用的

7. 好东西:PerFieldAnalyzerWrapper

经常的,我们会遇到这样的索引:一个Doc中有多个Field,每个Field中存储的值是不一样的。比如:一个域:partnum,存储的值是"Q36",存储的方式是Store,但是NOTANALYZED(也就是要求将Q36作为一个整体进行索引);另一个域:description,存储的值是"Illidium Space Modulator"",存储的方式是Store,同时是ANALYZED。然后,我们需要利用QueryParser来针对字符串"partnum:Q36 AND SPACE"进行搜索。

这时,就会遇到一个问题:用哪种Analyzer呢?因为QueryParser的构造函数中,只能放入一个Analyzer,而这里,partnum域是NOTANALYZED,而description域是ANALYZED。似乎Lucene自带的Analyzer是无法同时满足这两个域的搜索要求的。那么,这里的PerFieldAnalyzerWrapper就可以帮忙了。它可以在默认Analyzer的基础上,针对特定域可以绑定一个特定的Analyzer。然后,我们将PerFiledAnalyzerWrapper所创建的这个“混合”分析器,放入QueryParser的构造方法中就可以了。具体例子代码如下:

PerFieldAnalyzerWrapper analyzer = new PerFieldAnalyzerWrapper(new SimpleAnalyzer()); //先构建一个PerFieldAnalyzerWrapper实例,放入缺省的分析器
    analyzer.addAnalyzer("partnum", new KeywordAnalyzer()); //给特定Field绑定特定Analyzer
    Query query = new QueryParser(Version.LUCENE_30, "description", analyzer).parse("partnum:Q36 AND SPACE"); //这里就要采用PerFieldAnalyzerWrapper分析器了

《Lucene in Action 第二版》第4章节 学习总结 -- Lucene中的分析的更多相关文章

  1. 《Lucene in Action第二版》学习总结---如何在Windows下编译luceneinAction2Edition源码包

    1. 下载此源码包,位置是: www.manning.com/hatcher3,得到:lia2e.tar.gz,然后解压缩得到目录:lia2e,为了以后能辨识,我将此目录改名为:luceneinAct ...

  2. 《Lucene in Action 第二版》第三章节的学习总结----IndexSearcher以及Term和QueryParser

    本章节告诉我们怎么用搜索.通过这章节的学习,虽然搜索的内部原理不清楚,但是至少应该学会简单的编写搜索程序了本章节,需要掌握如下几个主要API1.IndexSearcher类:搜索索引的门户,发起者. ...

  3. 《Lucene in Action》(第二版) 第一章节的学习总结 ---- 用最少的代码创建索引和搜索

    第一章节是介绍性质,但是通过这一章节的学习,我理解到如下概念: 1.Lucene由两部分组成:索引和搜索.索引是通过对原始数据的解析,形成索引的过程:而搜索则是针对用户输入的查找要求,从索引中找到匹配 ...

  4. lucene实战(第二版)学习笔记

    初识Lucene 构建索引 为应用程序添加搜索功能 Lucene的分析过程

  5. 《TomCat与Java Web开发技术详解》(第二版) 第一章节的学习总结--HTTP组成+基本访问方式

    1.需要看懂HTML文件中的组成元素的基本含义.不同的组成元素,可以使得HTML支持文本,图片(img,将图片发给客户端),静态音频/视频(embed src,将音频视频发给客户端),超链接(href ...

  6. 采用WPF开发第二版OFD阅读器,持续完善中,敬请期待!

    本人研究OFD多年,采用C#和QT开发了一系列ofd相关软件.在这些产品中,阅读器始终占据着非常重要的位置.可以说,阅读器是直接面向最终客户的产品.是集OFD各类知识之大成的产品.市面上的阅读器产品林 ...

  7. 《selenium2 Java 自动化测试实战(第二版)》 更新2016.5.3

    java 版来了!! 本文档在<selenium2 Python 自动化测试实战>的基础上,将代码与实例替换为java ,当然,部分章节有变更.这主要更语言本身的特点有关.集合和java下 ...

  8. 简单的web三层架构系统【第二版】

    昨天写了 web三层架构的第一版,准确的说是三层架构的前期,顶多算是个二层架构,要慢慢完善. 第一版里,程序虽说能运行起来,但是有一个缺陷,就是里面的SQL语句,是使用的拼接字符进行执行.这样安全系数 ...

  9. Lucene.net站内搜索—6、站内搜索第二版

    目录 Lucene.net站内搜索—1.SEO优化 Lucene.net站内搜索—2.Lucene.Net简介和分词Lucene.net站内搜索—3.最简单搜索引擎代码Lucene.net站内搜索—4 ...

随机推荐

  1. 洛谷——P1991 无线通讯网

    P1991 无线通讯网 题目描述 国防部计划用无线网络连接若干个边防哨所.2 种不同的通讯技术用来搭建无线网络: 每个边防哨所都要配备无线电收发器:有一些哨所还可以增配卫星电话. 任意两个配备了一条卫 ...

  2. POJ 2109 Inner Vertices(扫描线+树状数组)

    [题目链接] http://poj.org/problem?id=3109 [题目大意] 在一个棋盘上放满白子,现在把一些白子变成黑子, 如果一个白子上下左右都有黑子,就会变成黑子,问最终黑子个数 [ ...

  3. devexpress XtraReport报表 ---主从报表

    private void GetWqpWorkPrinter(List<ReelListMagt> list, string WorkDate, User user) { ReelList ...

  4. Flex this

    为了便于对比和叙述,我们先上一段最简单的js+html代码:<input type="button" value="test" id="htmB ...

  5. 用js怎么控制submit提交表单

    需求: 1. 要在点击submit按钮的时候,弹出一个询问框,"你确定要修改?".如果按了"确定"那么就提交表单,否则就保留在原页面,既不提交不跳转. 2. 要 ...

  6. BeagleBone Black板第四课:简单LED控制实验

    BBB板第四课:简单LED控制实验 学习BBB板的终于目的是想像单片机一样做控制,但控制思路全然不一样(Linux下控制硬件设备实质就是对相关设备虚拟文件的读写).研究了几天头都大了还是没有进展,网上 ...

  7. Linux zip

    压缩文件: zip -r res.zip [src/] [abc.txt] 解压文件: unzip res.zip -d dir_path

  8. ElasticSearch的按日期排序问题

    ES中有一个sort域,类型为date,格式是: yyyy-MM-dd HH:mm:ss 但是,在实际应用中,想仅仅按yyyy-MM-dd排序.我的处理过程是,用es的script,提取出日期,然后按 ...

  9. SOYO的主板如何进入BIOS系统

    1 开机按Del键进入BIOS系统   2 进入Advanced BIOS Features   3 选择 Hard Disk Boot Priority 按ENTER   4 选择要启动的设备,比如 ...

  10. phpcms前台任意代码执行漏洞(php<5.3)

    phpcms v9 中 string2array()函数使用了eval函数,在多个地方可能造成代码执行漏洞 /phpsso_server/phpcms/libs/functions/global.fu ...