Lucene 核心攻略

Lucene 核心攻略

lucene的检索算法属于索引检索,即用空间来换取时间,对需要检索的文件、字符流进行全文索引,在检索的时候对索引进行快速的检索,得到检索位置,这个位置记录检索词出现的文件路径或者某个关键词。

analysis:分析器,切词

document:索引存储时的文档结构管理器,类似表结构

index:索引管理,包括建立,删除索引

queryParser:查询分析器,实现查询关键词的运算

search:检索管理,根据查询条件,检索得到结果

store:数据存储管理,IO操作

Directory:索引存放的位置;lucene 提供了两种索引存放的位置,一种是磁盘,一种是内存。

Hits:在搜索完成之后,需要把搜索结果返回并显示给用户,只有这样才算是完成搜索的目的。

IndexWriter:用于更新或创建索引。

Lucene的索引结构是文档(Document)形式的。

1.将文档传给分词组件(Tokenizer),分词组件根据标点符号和停词将文档分成词元(Token),并将标点符号和停词去掉。

2.再将词元传给语言处理组件(Linguistic Processor) ,词元会变成最基本的词根形式。

3.得到的词元传给索引组件(Indexer),索引组件处理得到索引结构,得到关键字、出现频率、出现位置分别作为词典文件

(Term Dictionary)、频率文件(frequencies)和位置文件(positions)保存起来,然后通过二元搜索算法快速查找关键字。

示例:

一篇文档有多种信息,如题目,作者,修改时间,内容等。

不同类型的信息用不同的Field 来表示,在本例子中,一共有两类信息进行了索引,一个是文件路径,一个是文件内容。

其中FileReader 的SRC_FILE 就表示要索引的源文件。

索引建立步骤:

1、创建Directory

2、创建Writer

3、创建文档并且添加索引

4、查询索引的基本信息

5、删除和更新索引

public class HelloLucene {

public static void main(String[] args) throws IOException, ParseException {

// 0. Specify the analyzer for tokenizing text.

// The same analyzer should be used for indexing and searching

StandardAnalyzer analyzer = new StandardAnalyzer(Version.LUCENE_40);

// 1. create the index

Directory index = new RAMDirectory();

IndexWriterConfig config = new IndexWriterConfig(Version.LUCENE_40, analyzer);

IndexWriter w = new IndexWriter(index, config);

addDoc(w, "Lucene in Action", "193398817");

addDoc(w, "Lucene for Dummies", "55320055Z");

addDoc(w, "Managing Gigabytes", "55063554A");

addDoc(w, "The Art of Computer Science", "9900333X");

w.close();

// 2. query

String querystr = args.length > 0 ? args[0] : "lucene";

// the "title" arg specifies the default field to use

// when no field is explicitly specified in the query.

Query q = new QueryParser(Version.LUCENE_40, "title", analyzer).parse(querystr);

// 3. search

int hitsPerPage = 10;

IndexReader reader = DirectoryReader.open(index);

IndexSearcher searcher = new IndexSearcher(reader);

TopScoreDocCollector collector = TopScoreDocCollector.create(hitsPerPage, true);

searcher.search(q, collector);

ScoreDoc[] hits = collector.topDocs().scoreDocs;

// 4. display results

System.out.println("Found " + hits.length + " hits.");

for(int i=0;i

int docId = hits[i].doc;

Document d = searcher.doc(docId);

System.out.println((i + 1) + ". " + d.get("isbn") + "\t" + d.get("title"));

}

// reader can only be closed when there

// is no need to access the documents any more.

reader.close();

}

private static void addDoc(IndexWriter w, String title, String isbn) throws IOException {

Document doc = new Document();

doc.add(new TextField("title", title, Field.Store.YES));

// use a string field for isbn because we don't want it tokenized

doc.add(new StringField("isbn", isbn, Field.Store.YES));

w.addDocument(doc);

}

}

搜索过程:示例如上

IndexReader 将磁盘上的索引信息读入到内存,INDEX_DIR 就是索引文件存放的位置。

创建IndexSearcher 准备进行搜索。

创建Analyer 用来对查询语句进行词法分析和语言处理。

创建QueryParser 用来对查询语句进行语法分析。

QueryParser 调用parser 进行语法分析,形成查询语法树,放到Query 中。

IndexSearcher 调用search 对查询语法树Query 进行搜索,得到结果TopScoreDocCollector 。

在Lucene中,词典和倒排是分开存储的,词典存储在.tii和.tis文件中,而倒排又分为两部分存储,第一部分是文档号和词频信息,存储在.frq中;另一部分是词的位置信息,存储在.prx文件中。

所谓正向信息:

lucene 在存储它的全文索引结构时,是有层次结构的,

涉及到5个层次:索引(Index) –> 段(segment) –> 文档(Document) –> 域(Field) –> 词(Term)

索引(Index):一个目录一个索引,在Lucene中一个索引是放在一个文件夹中的。

段(Segment):一个索引可以包含多个段,段与段之间是独立的,添加新文档可以生成新的段,不同的段可以合并。

文档(Document):文档是我们建索引的基本单位,不同的文档是保存在不同的段中的,一个段可以包含多篇文档。

域(Field):一篇文档包含不同类型的信息,可以分开索引.

词(Term):词是索引的最小单位,是经过词法分析和语言处理后的字符串。

所谓反向信息:

保存了词典到倒排表的映射:词(Term) –> 文档(Document)

更多内容请关注每日编程。


分享到:


相關文章: