通过第四章的学习,可以了解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. Lightoj 1348 Aladdin and the Return Journey (树链剖分)(线段树单点修改区间求和)

    Finally the Great Magical Lamp was in Aladdin's hand. Now he wanted to return home. But he didn't wa ...

  2. luogu P3818 小A和uim之大逃离 II

    题目背景 话说上回……还是参见 https://www.luogu.org/problem/show?pid=1373 吧 小a和uim再次来到雨林中探险.突然一阵南风吹来,一片乌云从南部天边急涌过来 ...

  3. 洛谷 P3804 后缀自动机

    题目描述 给定一个只包含小写字母的字符串SS , 请你求出 SS 的所有出现次数不为 11 的子串的出现次数乘上该子串长度的最大值. 输入输出格式 输入格式: 一行一个仅包含小写字母的字符串SS 输出 ...

  4. 用Xcode6的Leaks检测内存泄漏

    用xcode打开项目之后,选择Product - Profile: 在弹出的窗口中选择Leaks: 然后在设备解锁的情况下,选择Leaks再点击左上角的红色按钮开始运行APP: 红色的柱子表示有内存泄 ...

  5. Bluetooth篇 开发实例之八 匹配

    自己写的App匹配蓝牙设备,不需要通过系统设置去连接. 匹配和通信是两回事. 用过Android系统设置(Setting)的人都知道蓝牙搜索之后可以建立配对和解除配对,但是这两项功能的函数没有在SDK ...

  6. linux下批量更改一个目下的目录和文件的权限

    对于网站目录我们一般设置目录的权限是755, 而文件的权限是644  ,上传目录另设 比如我们要设置web目录下的所有目录的权限是755,文件的目录是644,那么我们可以批量修改吗?答案是肯定的, 就 ...

  7. mysql 的常用查询

    Ø 基本常用查询 --select select * from student;   --all 查询所有 select all sex from student;   --distinct 过滤重复 ...

  8. Solr In Action 中文版 第一章(三)

    3.1              为什么选用Solr? 在本节中.我们希望能够提供一些关键信息来帮助于你推断Solr是否是贵公司技术方案的正确选择.我们先从Solr吸引软件架构师的方面说起. 3.1  ...

  9. 常见java异常

    1. java.lang.NullPointerException(空指针异常)  调用了未经初始化的对象或者是不存在的对象 经常出现在创建图片,调用数组这些操作中,比如图片未经初始化,或者图片创建时 ...

  10. 2017.7.31 ELK+logback+redis的使用

    参考来自:spring mvc+ELK从头开始搭建日志平台 0 前提 ELK安装成功 redis安装成功 使用logback的项目运行成功 1 配置文件 1.1 pom.xml 为了使用logback ...