通过第四章的学习,可以了解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. INNO SETUP脚本向导创建的基本脚本

    脚本范例分析:先来看看一段用INNO SETUP脚本向导创建的基本脚本的[Setup]段: [Setup]   AppName=Premiere 6.5 汉化补丁-----------------(程 ...

  2. 【Linux】CentOS7上设置快捷键 随时补充

    ---------------------------------------------------------------------------------------------------- ...

  3. 设计模式之工厂模式之工厂方法(php实现)

    github: git@github.com:ZQCard/design_pattern.git /** * 工厂方法 * 使用开闭原则来分析下工厂方法模式.当有新的产品产生时,只要按照抽象产品角色. ...

  4. selenium 定位元素方式大全

    starts-with 顾名思义,匹配一个属性开始位置的关键字 contains 匹配一个属性值中包含的字符串 text() 匹配的是显示文本信息,此处也可以用来做定位用 eg //input[sta ...

  5. java内存溢出分析工具:jmap使用实战

    在一次解决系统tomcat老是内存撑到头,然后崩溃的问题时,使用到了jmap. 1 使用命令 在环境是linux+jdk1.5以上,这个工具是自带的,路径在JDK_HOME/bin/下 jmap -h ...

  6. 信号驱动IO

    [1]信号驱动IO 应用程序:1)应用程序要捕捉SIGIO信号           signal(SIGIO, handler); 2)应用程序要指定进程为文件的属主,设置当前的文件描述为当前的调用进 ...

  7. python下性能提示

    性能提示 3.1 嵌套if/else结构比一系列单选if结构块,因为只要有一个条件满足,其余测试就会终止. 3.2 在嵌套if/else结构中,把最可能成立的条件放在该嵌套结构的开始处.和把不常见的条 ...

  8. .net的远程调用

    .Net远程调用(转自:http://www.cnblogs.com/omilan/articles/3191378.html) 看到了这.net远程调用的讲解,觉得不错,拿来分享!! .Net对于远 ...

  9. ODS与EDW的区别

    http://blog.csdn.net/bitcarmanlee/article/details/51013474 根据自己的理解与实际项目经验,说说ODS与EDW的异同.如果有不对的地方,欢迎大家 ...

  10. asp.net购物车,订单以及模拟支付宝支付(四)---模拟支付宝支付

    下完订单之后到支付宝付款,成功之后再返回来修改订单状态.由于只是测试,所以就没有真正的连接到支付宝,用的是一个模拟支付宝的程序 下载地址:支付宝模拟程序 这是一个vs2010的项目,本来网上找了一个模 ...