Lucene使用实例

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原理与代码分析

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值