现在的位置: 首页 > 综合 > 正文

【转载】lucene整理 — 概念 搜索 排序

2013年05月16日 ⁄ 综合 ⁄ 共 6438字 ⁄ 字号 评论关闭

 

 

【摘录】

http://blog.csdn.net/xiaoping8411/article/details/5409940

 

lucene整理1 -- 概念

分类: lucene2010-03-23
22:34
 52人阅读 评论(0) 收藏 举报

1.    概述

Lucene是一个全文检索引擎的架构,提供了完整的查询引擎和索引引擎。Lucene以其方便使用、快速实施以及灵活性受到广泛的关注。它可以方便地嵌入到各种应用中实现针对应用的全文索引、检索功能,本总结使用lucene--2.3.2

2.    lucene 的包结构

1org.apache.lucene.analysis对需要建立索引的文本进行分词、过滤等操作语言分析器,主要用于的切词Analyzer是一个抽象类,管理对文本内容的切分词规则。

2org.apache.lucene.analysis.standard是标准分析器

3org.apache.lucene.document提供对DocumentField的各种操作的支持。索引存储时的文档结构管理,类似于关系型数据库的表结构。Document相对于关系型数据库的记录对象,Field主要负责字段的管理。

4org.apache.lucene.index是最重要的包,用于向Lucene提供建立索引时各种操作的支持。索引管理,包括索引建立、删除等。索引包是整个系统核心,全文检索的根本就是为每个切出来的词建索引,查询时就只需要遍历索引,而不需要去正文中遍历,从而极大的提高检索效率。

5org.apache.lucene.queryParser提供检索时的分析支持。查询分析器,实现查询关键词间的运算,如与、或、非等。

6org.apache.lucene.search 负责检索。检索管理,根据查询条件,检索得到结果。

7org.apache.lucene.store提供对索引存储的支持。数据存储管理,主要包括一些底层的I/0操作。

8org.apache.lucene.util提供一些常用工具类和常量类的支持

3.    索引文件格式

a)         .fnm格式  包含了Document中所有field名称

b)        .fdt.fdx格式  .fdt文件用于存储具有Store.YES属性的Field的数据;.fdx是一个索引,用于存储Document.fdt中的位置。

c)        .tis .tii格式  .tis文件用于存储分词后的词条(Term),而.tii就是它的索引文件,它表明了每个.tis文件中的词条的位置。

d)        deletable格式 文档被删除后,会首先在deletable文件中留下一个记录,要真正删除时,才将索引除去。

e)         复合索引格式 .cfs

使用IndexWriteruseCompoundFile()  默认为True

 

 

1.    lucene中主要的类

1.1. Document文档类

1.1.1.常用方法

方法

描述

void add(Field
field)

Document对象中添加字段

void
removeField(String name)

删除字段。若多个字段以同一个字段名存在,则删除首先添加的字段;若不存在,则Document保持不变

void
removeFields(String name)

删除所有字段。若字段不存在,则Document保持不变

Field getFieldString
name

若多个字段以同一个字段名存在,则返回首先添加的字段;若字段不存在,则Document保持不变

Enumeration
fields()

返回Document对象的所有字段,以枚举类型返回

Field []
getFields(String name)

根据名称得到一个Field的数组

String []
getValues(String name)

根据名称得到一个Field的值的数组

 

1.1.2.示例

Document doc1 = new Document();

doc1.add(new Field("name", "word1
word2 word3"
,

Field.Store.NO,Field.Index.TOKENIZED));

Document doc2 = new Document();

doc2.add(new Field("name", "word1
word2 word3"
,

Field.Store.NO,Field.Index.TOKENIZED));

1.2. Field字段类

1.2.1.构造方法

1)        public Field(String
name,String value,Store store,Index index);//
直接的字符串方式

2)        public Field(String
name,String value,Store store,Index index,TermVector termVector);

3)        public Field(String
name,String value,Reader reader);//
使用Reader从外部传入

4)        public Field(String
name,String value,Reader reader,TermVector termVector);

5)        public Field(String
name,byte[] value,Store store)//
使用直接的二进制byte传入

Field值为二进制时,可以使用Lucene的压缩功能将其值进行压缩。

1.2.2.Store

静态属性

描述

Store.NO

表示该Field不需要存储

Store.YES

表示该Field需要存储

Store.COMPRESS

表示用压缩方式来保存这个Field的值

1.2.3.Index

静态属性

描述

Index.NO

不需要索引

Index.TOKENIZED

先被分词再被索引

Index.UN_TOKENIZED

不对该Field进行分词,但会对它进行索引

Index.NO_NORMS

对该Field进行索引,但是不使用Analyzer,同时禁止它参加评分,主要是为了减少内存的消耗。

 

1.2.4.示例

new Field("name", "word1 word2
word3",Field.Store.YES,Field.Index.TOKENIZED)

 

1.3. IndexWriter

1.3.1.构造方法

1)        public
IndexWriter(String path,Analyzer a,Boolean create)

2)        public
IndexWriter(File path,Analyzer a,Boolean create)

3)        public
IndexWriter(Directory d,Analyzer a,Boolean create)

第一个参数:索引存放在什么地方

第二个参数:分析器,继承自org.apache.lucene.analysis.Analyzer

第三个参数:为true时,IndexWriter不管目录内是否已经有索引了,一律清空,重新建立;当为false时,则IndexWriter会在原有基础上增量添加索引。所以在更新的过程中,需要设置该值为false

1.3.2.添加文档

public void addDocument(Document doc)

public void addDocument(Document doc,Analyzer analyzer)//使用一个开发者自定义的,而非事先在构建IndexWriter时声明的Analyzer来进行分析

writer.addDocument(doc1);

1.3.3.性能参数

1)        mergeFactor控制Lucene在把索引从内存写入磁盘上的文件系统时内存中最大的Document数量,同时它还控制内存中最大的Segment数量。默认为10.

writer.setMergeFactor(10);

2)        maxMergeDocs限制一个Segment中最大的文档数量。一个较大的maxMergeDocs适用于对大批量的文档建立索引,增量式的索引则应使用较小的maxMergeDocs

writer.setMaxMergeDocs(1000);

3)        minMergeDocs用于控制内存中持有的文档数量的,它对磁盘上的Segment大小没有任何影响。

1.3.4.限制Field的长度

maxFieldLength限制Field的长度,默认值为10000.最大值100000个。

public void setMaxFieldLength(int maxFieldLength)

writer.addDocument(doc1);

writer.setMaxFieldLength(100000);

writer.addDocument(doc2);

1.3.5.复合索引格式

setUseCompoundFile(Boolean) 默认true

writer.setUseCompoundFile(true);//复合索引

writer.setUseCompoundFile(false);

1.3.6.优化索引

writer.optimize();

将磁盘上的多个segment进行合并,组成一个全新的segment。这种方法并不会增加建索时的速度,反而会降低建索的速度。所以应该在建完索引后在调用这个函数

1.3.7.示例

IndexWriter writer = new IndexWriter(path, new
StandardAnalyzer(), true);

writer.addDocument(doc1);

writer.addDocument(doc2);

Sytem.out.println(writer.docCount());

writer.close();

IndexSearcher searcher = new IndexSearcher(path);

Hits hits = null;

Query query = null;

QueryParser parser =new QueryParser("name", new
StandardAnalyzer());

query =parser.parse("word1");

hits = searcher.search(query);

System.out.println("查找 word1 " +
hits.length() + "
个结果");

 

1.4. Directory

Directory:用于索引的存放位置

a)         FSDirectory.getDirectory(path,
true)
第二个参数表示删除掉目录内原有内容

IndexWriter writer = new
IndexWriter(FSDirectory.getDirectory(path, true), new StandardAnalyzer(),
true);//
删除原有索引

FSDirectory fsDir=FSDirectory.getDirectory(path,true);

IndexWriter writer = new IndexWriter(fsDir, new
StandardAnalyzer(), true);

b)        RAMDirectory在内存中存放,读取速度快,但程序一运行结束,它的内容就不存在了

RAMDirectory ramDir=new RAMDirectory();

IndexWriter writer = new IndexWriter(ramDir, new
StandardAnalyzer(), true);

 

IndexWriter writer = new IndexWriter(new RAMDirectory(), new
StandardAnalyzer(), true);

1.5. IndexReader

IndexReader类――索引的读取工具

1.5.1.删除文档

IndexReader reader=IndexReader.open(path);

reader.deleteDocument(0);//删除第一个

reader.close();

1.5.2.反删除

reader.undeleteAll();

1.5.3.按字段删除

reader.deleteDocuments(new
Term("name","word1"));

若要真正物理删除,则只需使用IndexWriter对索引optimize一次即可!

1.5.4.示例

IndexReader reader=IndexReader.open(path);

           for(int i=0;i<reader.numDocs();i++){

              System.out.println(reader.document(i));

           }

           System.out.println("版本:"+reader.getVersion());

           System.out.println("索引内的文档数量:"+reader.numDocs());

           //reader.deleteDocuments(new
Term("name","word1"));

           Term term1=new Term("name","word1");

           TermDocs docs=reader.termDocs(term1);

           while(docs.next())

           {

              System.out.println("含有所查找的"+term1+"Document的编号为"+docs.doc());

              System.out.println("Term在文档中的出现次数"+docs.freq());

           }

           reader.close();

 

1.6. IndexModifier

集成了IndexWriter的大部分功能和IndexReader中对索引删除的功能 ------ Lucene2.0的新类

 

1.6.1.示例

public static void main(String[]
args) 
throws Exception {

       IndexModifier modifier=new IndexModifier("C://Q1",new StandardAnalyzer(),true);

       Document doc1=new Document();

       doc1.add(new Field("bookname","钢铁是怎样炼成的",Field.Store.YES,Field.Index.TOKENIZED));

       Document doc2=new Document();

       doc2.add(new Field("bookname","山山水水",Field.Store.YES,Field.Index.TOKENIZED));

       modifier.addDocument(doc1);

       modifier.addDocument(doc2);

      

       System.out.println(modifier.docCount());

抱歉!评论已关闭.