您的位置:首页 > 其它

Lucene使用实例

2015-06-23 16:42 363 查看
Lucene全文检索大体分两个部分:索引创建(Indexing)和搜索索引(Search)

1. 索引过程

1) 有一系列被索引文件(此处所指即文本数据)

2) 被索引文件经过语法分析和语言处理形成一系列词(Term)。

3) 经过索引创建形成词典和反向索引表。

4) 通过索引存储将索引写入硬盘。
2. 搜索过程

1) 用户输入查询语句。

2) 对查询语句经过语法分析和语言分析得到一系列词(Term)。

3) 通过语法分析得到一个查询树。

4) 通过索引存储将索引读入到内存。

5) 利用查询树搜索索引,从而得到每个词(Term)的文档链表,对文档链表进行交,差,并得到结果文档。

6) 将搜索到的结果文档对查询的相关性进行排序。

7) 返回查询结果给用户。

Lucene目前版本5.2.1,下面我们以这个版本演示一下Lucene的使用代码。

下面我们以一个实例说明:

引入依赖包:

<properties>
<lucene.version>5.2.1</lucene.version>
</properties>

<dependencies>
<dependency>
<groupId> org.apache.lucene</groupId>
<artifactId> lucene-core</artifactId>
<version> ${lucene.version}</version>
</dependency>
<dependency>
<groupId> org.apache.lucene</groupId>
<artifactId> lucene-analyzers-common</artifactId>
<version> ${lucene.version}</version>
</dependency>
<dependency>
<groupId> org.apache.lucene</groupId>
<artifactId> lucene-queryparser</artifactId>
<version> ${lucene.version}</version>
</dependency>
</dependencies>
实例对象:

package cn.slimsmart.lucene.demo.example;

import java.util.ArrayList;
import java.util.List;

public class User {

private String id;
private String name;
private String desc;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}

public static List<User> getInitList(){
List<User> list = new ArrayList<User>();
User user = new User();
user.setId("10001");
user.setName("张三");
user.setDesc("张三是个农民,勤劳致富,奔小康");
list.add(user);
user = new User();
user.setId("20001");
user.setName("李四");
user.setDesc("李四是个企业家,白手起家,致富一方");
list.add(user);
user = new User();
user.setId("11111");
user.setName("王五");
user.setDesc("王五好吃懒做,溜须拍马,跟着李四,也过着小康的日子");
list.add(user);
return list;
}
}
使用实例:

package cn.slimsmart.lucene.demo.example;

import java.io.File;
import java.nio.file.Paths;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field.Store;
import org.apache.lucene.document.StringField;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.IndexWriterConfig.OpenMode;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;

public class Test {

public static void main(String[] args) throws Exception {
createIndex();
search();
}

public static void createIndex() throws Exception {
String pathFile = new File("src/main/resources").getAbsolutePath();
// 索引文件的保存位置
Directory dir = FSDirectory.open(Paths.get(pathFile));
// 分析器
Analyzer analyzer = new StandardAnalyzer();
// 配置类
IndexWriterConfig iwc = new IndexWriterConfig(analyzer);
/**
APPEND:总是追加,可能会导致错误,索引还会重复,导致返回多次结果
CREATE:清空重建(推荐)
CREATE_OR_APPEND【默认】:创建或追加
*/
iwc.setOpenMode(OpenMode.CREATE);// 创建模式 OpenMode.CREATE_OR_APPEND 添加模式
IndexWriter writer =  new IndexWriter(dir, iwc);
for (User u : User.getInitList()) {
Document doc = new Document();
doc.add(new StringField("id", u.getId(), Store.YES));
doc.add(new StringField("name",u.getName(), Store.YES));
doc.add(new StringField("desc", u.getDesc(), Store.YES));
System.out.println(doc);
writer.addDocument(doc);
}
System.out.println("初始化完毕");
writer.commit();
writer.close();
}

public static void search() throws Exception {
String pathFile = new File("src/main/resources").getAbsolutePath();
Directory dir = FSDirectory.open(Paths.get(pathFile));
IndexReader reader=DirectoryReader.open(dir);
IndexSearcher searcher=new IndexSearcher(reader);
//对于中文查询,需要分词
Term term=new Term("name", "张三");
Query query= new TermQuery(term);
//模糊搜索
//Term term=new Term("desc", "*小康*");
//Query query= new WildcardQuery(term);
//n 查找top
TopDocs topdocs=searcher.search(query, 2);
ScoreDoc[] scoreDocs=topdocs.scoreDocs;
System.out.println("查询结果总数:" + topdocs.totalHits);
System.out.println("最大的评分:"+topdocs.getMaxScore());
for(int i=0; i < scoreDocs.length; i++) {
int doc = scoreDocs[i].doc;
Document document = searcher.doc(doc);
System.out.println("docid:" + scoreDocs[i].doc);
System.out.println("scors:" + scoreDocs[i].score);
System.out.println("shardIndex:" + scoreDocs[i].shardIndex);
System.out.println("id:"+document.get("id")+",name:"+document.get("name")+",desc:"+document.get("desc"));
}
reader.close();
}
}
运行可以看到:

初始化完毕
查询结果总数:1
最大的评分:1.4054651
docid:0
scors:1.4054651
shardIndex:0
id:10001,name:张三,desc:张三是个农民,勤劳致富,奔小康

注:由于lucene自带的分词方式对中文分词十分的不友好,所以在对一段中文中的某个词组进行搜索时,需要在创建索引是对其进行分词,如搜索desc中的“致富”,无法获取结果。

参考文章:

1.Lucene:基于Java的全文检索引擎简介

2.Lucene原理与代码分析
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  全文检索 lucene