`
newqinhao
  • 浏览: 141141 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

传智播客-----Lucene介绍

阅读更多
今天汤阳光给我们讲了Lucene,让我们对它有了初步的认识!老师是这样介绍的:

1,lucene是众多搜索引擎中的一个,就像持久层除了Hibernate外也有很多其它框架
一样。Lucene是一个开发工具包,我们可以使用他为应用程序添加全文检索的功能。

2,目前已经有很多应用程序的搜索功能是基于 Lucene 的,比如 Eclipse 的帮助系
统的搜索功能。 还有其他很多的网站的应用程序使用了Lucene。

3,Lucene 能够为文本类型的数据建立索引,所以你只要能把你要索引的数据格式转
化的文本的,Lucene 就能对你的文档进行索引和搜索。


==================================================

1,准备环境:添加jar包
   lucene-core-2.4.0.jar(核心);
   lucene-analyzers-2.4.0.jar(分词器);
   lucene-highlighter-2.4.0.jar(高亮器);

a) 建立索引.
b) 进行搜索.


2,构造IndexWriter。IndexWriter是Lucene用来创建索引的一个核心的类。使用
构造方法IndexWriter(Directory d, Analyzer a, MaxFieldLength mfl); 如果
索引不存在,就会被创建。

Directory,代表了 Lucene 的索引的存储的位置。这是一个抽象类,常用的有两
个实现,第一个是 FSDirectory,它表示一个存储在文件系统中的索引位置。第
二个是 RAMDirectory,它表示一个存储在内存当中的索引位置。

Analyzer,在一个文档被索引之前,首先需要对文档内容进行分词处理,这部分
工作就是由 Analyzer 来做的。Analyzer 类是一个抽象类,它有多个实现。针对
不同的语言和应用需要选择适合的 Analyzer。Analyzer 把分词后的内容交给
IndexWriter 来建立索引。

MaxFieldLength,用于限制Field的大小。这个变量可以让用户有计划地对大文档
Field进行截取。假如取值为10000,就只索引每个Field的前10000个Term(关键
字)。也就是说每个Field中只有前10000个Term(关键字)建立索引,除此之外
的部分都不会被Lucene索引,当然也不能被搜索到。


3,创建索引,使用方法IndexWriter.addDocument(Document doc)。

Document,是用来描述Lucene文档结构的。任何需要进行索引的数据都必须转化
成Document对象。Document是索引和搜索的最基本单元,是一组Field的集合。

Field,组成Document的元素,用来描述一个文档的某个属性的,比如一封电子邮
件的标题和内容可以用两个Field对象分别描述。Field是由name和value组成的,
value只接受字符串(非字符串类型要先转换成字符串才行)。在构造Field时还
要指定Store和Index。

Field.Store,指定Field是否或怎样存储。
  Store.NO,不存储。
  Store.YES,存储。
  Store.COMPRESS,压缩后存储(数据量很大的时候可以使用,但要考虑效率)。

Field.Index,指定Field是否或怎么被索引。
  Index.NO,不索引(不索引就不能被搜索到)。
  Index.ANALYZED,(以前版本中为TOKENIZED),分词后索引。
  Index.NOT_ANALYZED,(以前版本中为UN_TOKENIZED),不分词,直接索引(把
                      整个Field值做为一个term)。

当完成了索引操作后,一定要调用IndexWriter.close()方法。


4,删除索引,IndexWriter.deleteDocuments(Term term);会删除索引文件里含
有指定Term的所有Document。

Term,是搜索的基本单位。代表某个Field中出现的某个关键字。 


5,更新索引,IndexWriter.updateDocument(Term term, Document doc)。实际上是
先删除再创建索引,就是说如果有多条符合条件的Document,更新后只有一条。


6,搜索,使用类IndexSearcher。
查询方法为IndexSearcher.search(Query, Filter, int);
Query,查询对象,把用户输入的查询字符串封装成Lucene能够识别的Query。
Filter,用来过虑搜索结果。
第三个参数(int类型),最多返回的Document的数量。
返回的是一个TopDocs类型的对象,调用TopDocs.scoreDocs得到查询结果。

ScoreDoc.doc返回文档的内部编号。
IndexSearcher.doc(scoreDocs[i].doc) 通过编号,拿到文档。

Query可以用QueryParser解析查询字符串生成。使用构造方法为
QueryParser(String defaultFieldName, Analyzer a):
  1,第一个参数为默认查询的Field;
  2,第二个参数为使用的分词器;
  3,这里用的分词器要和建立索引时用的分词器一致,否则可能会搜索不到结果;
  4,使用parse(String)方法解析查询内容。


7,测试LuceneIndexDao的增删改查方法,把LuceneIndexDao做为练习,要求通过
LuceneIndexDaoTest中的单元测试。


==================================================

*** 1,Directory,
有两个:
  a) FSDirectory,将索引放到磁盘中。
  b) RAMDirectory,将索引放到内存中。速度快,但是在jvm退出之后,内存中
的索引就不存在了。可以在jvm退出之前调用另一个使用FSDirectory的
IndexWriter 把内存中的索引转存到文件系统中。
    相应的API为IndexWriter.addIndexesNoOptimize(Directory[]),注意这个调
用代码要放在内存中索引的操作RAMDirectory的IndexWriter关闭后,以便所有的
document都进入RAMDirectory。在创建RAMDirectory的实例时,可以使用无参的构
造方法,或是有一个参数的构造方法:可以指定一个文件路径,以便加载磁盘中的索
引到内存中。


*** 2,相关度排序,
Lucene的搜索结果默认按相关度排序的,所谓相关度,就是文档的得分。Lucene
有一个评分机制,就是对检索结果按某种标准进行评估,然后按分值的高低来对
结果进行排序。

a) 文档的得分与用户输入的关键字有关系,而且是实时运算的结果。得分会受关
键字在文档中出现的位置与次数等的影响。

b) 可以利用Boost影响Lucene查询结果的排序,通过设置Document的Boost来影响
文档的权重,以达到控制查询结果顺序的目的:Document.setBoost(float)。默
认值为1f,值越大,得分越高。

c) 也可以在查询时给Filed指定boost。当同样的term属于不同的field时,如果
field的boost不一样,其所属的文件的得分也不一样。
后面.

*** 3,Analyzer,
分词器,对文本资源进行切分,将文本按规则切分为一个个可以进行索引的最小
单位(关键字)。

对于英文的分词,是按照标点、空白等拆分单词,比较简单;而中文的分词就比
较复杂了,如”中华人民共和国“可以分为”中华”、“人民”、“共和国”,但不应有“华人”
这个词(不符合语义)。

中文分词几种常用的方式:
a) 单字分词,就是按照中文一个字一个字地进行分词。如:我们是中国人,效果:
  我\们\是\中\国\人。(StandardAnalyzer就是这样)。
b) 二分法:按两个字进行切分。如:我们是中国人,效果:我们\们是\是中\中
  国\国人。(CJKAnalyzer就是这样)。
c) 词库分词:按某种算法构造词,然后去匹配已建好的词库集合,如果匹配到就切
  分出来成为词语。通常词库分词被认为是最理想的中文分词算法,如:我们是中
  国人,效果为:我们\中国人。(使用MMAnalyzer)。


*** 4,Highlighter,高亮器,用于高亮显示匹配的关键字。
包含三个主要部分:
1) 格式化器:Formatter(使用SimpleHTMLFormatter,在构造时指定前缀和后缀)。
2) 计分器:Scorer(使用QueryScorer)。
3) 段划分器:Fragmenter(使用SimpleFragmenter,在构造时指定关键字所在的
   内容片段的长度)。

通过方法getBestFragment(Analyzer a, String fieldName,String text)实现高亮。
(如果进行高亮的field中没有出现关键字,返回null)。


* 5,查询,有两种方式:通过Query Parser解析查询字符串或使用API构建查询。
使用Query Parser时不匹分大小写。以下是常用的查询:

1) TermQuery,按Term(关键字)查询(term的值应是最终的关键字,英文应全部小写)。
   TermQuery(Term t);
   syntax: propertyName:keyword;

2) RangeQuery,指定范围查询。
   RangeQuery(Term lowerTerm, Term upperTerm, boolean inclusive);
   syntax: propertyName:[lower TO upper](包含lower和upper);
   syntax: propertyName:{lower TO upper}(不包含lower和upper);

3) PrefixQuery,前缀查询。
   PrefixQuery(Term prefix);
   syntax:propertyName:prefix*;

4) WildcardQuery,通配符查询,可以使用"?"代表一个字符,"*"代表0个或多个字符。
   (通配符不能出现在第一个位置上)
   WildcardQuery(Term term);
   syntax: propertyName:chars*chars?chars

5) MultiFieldQueryParser,在多个Field中查询。
   queryParser = MultiFieldQueryParser(String[] fields, Analyzer analyzer);
   Query query = parse(String query);
  
6) BooleanQuery,布尔查询。这个是一个组合的Query,可以把各种Query添加进
   去并标明他们的逻辑关系。
   TermQuery q1 = new TermQuery(new Term("title","javadoc"));
   TermQuery q2 = new TermQuery(new Term("content","term"));
   BooleanQuery boolQuery = new BooleanQuery();
   boolQuery.add(q1, Occur.MUST);
   boolQuery.add(q2, Occur.MUST_NOT);
  
   Occur.MUST,必须出现。
   Occur.MUST_NOT,必须未出现,不要单独使用。
   Occur.SHOULD,只有一个SHOULD时为必须出现,多于一个时为或的关系。

   syntax: + - AND NOT OR (必须为大写)。



分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics