【Lucene】创建第一个Lucene索引库

什么是Lucene?

Lucene是apache软件基金会发布的一个开放源代码的全文检索引擎工具包,由资深全文检索专家Doug Cutting所撰写,它是一个全文检索引擎的架构,提供了完整的创建索引和查询索引,以及部分文本分析的引擎,Lucene的目的是为软件开发人员提供一个简单易用的工具包,以方便在目标系统中实现全文检索的功能,或者是以此为基础建立起完整的全文检索引擎,Lucene在全文检索领域是一个经典的祖先,现在很多检索引擎都是在其基础上创建的,思想是相通的。

即:Lucene是根据关健字来搜索的文本搜索工具,只能在某个网站内部搜索文本内容,不能跨网站搜索


Lucene通常用在什么地方?


Lucene通常用在站内搜索中,例如:


Lucene在MVC的位置是dao层


Lucene存的是什么内容?

Lucene中存的就是一系列的二进制压缩文件和一些控制文件,它们位于计算机的硬盘上,

这些内容统称为索引库,索引库有二部份组成:

(1)原始记录

     存入到索引库中的原始文本,例如:中国好室友,没错,正是在下

(2)词汇表

     按照一定的拆分策略(即分词器)将原始记录中的每个字符拆开后,存入一个供将来搜索的表



为何网站的内部搜索要使用Lucene而不使用SQL?

(1)SQL只能针对数据库表搜索,不能直接针对硬盘上的文本搜索

(2)SQL没有相关度排名

(3)SQL搜索结果没有关健字高亮显示

(4)SQL需要数据库的支持,数据库本身需要内存开销较大,例如:Oracle

(5)SQL搜索有时较慢,尤其是数据库不在本地时,超慢,例如:Oracle


如何使用?

流程如下:

创建索引库:

1)  创建JavaBean对象

2)  创建Docment对象

3)  将JavaBean对象所有的属性值,均放到Document对象中去,属性名可以和JavaBean相同或不同

4)  创建IndexWriter对象

5)  将Document对象通过IndexWriter对象写入索引库中

6)  关闭IndexWriter对象

根据关键字查询索引库中的内容:

1)  创建IndexSearcher对象

2)  创建QueryParser对象

3)  创建Query对象来封装关键字

4)  用IndexSearcher对象去索引库中查询符合条件的前100条记录,不足100条记录的以实际为准

5)  获取符合条件的编号

6)  用indexSearcher对象去索引库中查询编号对应的Document对象

7)  将Document对象中的所有属性取出,再封装回JavaBean对象中去,并加入到集合中保存,以备将之用


下面就来开始第一个Lucene的案例吧

首先引入jar包,jar包可以直接去apache的官网下载

我们将以下jar包引入



首先创建一个Article对象

package cn.qblank.lucene;
/**
 * 文章
 * @author Administrator
 *
 */
public class Article {
	private Integer id;
	private String title;
	private String content;
	
	public Article(){}
	public Article(Integer id, String title, String content) {
		super();
		this.id = id;
		this.title = title;
		this.content = content;
	}
	
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getTitle() {
		return title;
	}
	public void setTitle(String title) {
		this.title = title;
	}
	public String getContent() {
		return content;
	}
	public void setContent(String content) {
		this.content = content;
	}
	
	@Override
	public String toString() {
		return "编号:" + id + "\n标题:" + title + "\n内容:" +content;
	}
	
}

然后创建一个索引库,将相应的内容存入进去

public void createIndexDB() throws IOException {
	//1.创建文章对象
	Article article = new Article(2, "中国好室友", "中国好室友,没错,正是在下");
	//2.创建document对象
	Document document = new Document();
	//3.将Aracle中的属性词绑定到document对象中
	/* 
	 * 参数一:document中的属性名叫xid,article对象中的属性名是id,一般docuemnt属性名是在实体类的属性名前面加个x
	 * 参数二:document对象中属性名的值,与article对象中相同
	 * 参数三:是否将(xid)属性值存入由原始记录表中的转存入词汇表中
	 * 		Store.YES表示会存入词汇表
	 * 		Store.No表示不会存入词汇表
	 * 参数四: 是否将(xid)属性值进行分词算法
	 * 		Index.ANALYZED表示该属性值会进行词汇拆分
	 * 		Index.NOT_ANALYZED表示不进行拆分(提倡非id值都进行拆分)
	 */
	document.add(new Field("xid", article.getId().toString(), Store.YES,Index.NOT_ANALYZED));
	document.add(new Field("xtitle", article.getTitle(), Store.YES,Index.ANALYZED));
	document.add(new Field("xcontent", article.getContent(), Store.YES,Index.ANALYZED));
	
	//最多将文本拆分出多少个词汇,LIMITED表示1w个,即只取前1w个词汇,如果不足1w个词汇,以实际为准
	MaxFieldLength maxFieldlength = MaxFieldLength.LIMITED;
	//Lucene索引库最终存入硬盘中的目录,例如:F:/LuceneDB
	FSDirectory directory = FSDirectory.open(new File("F:/LuceneDB"));
	//采用的分词策略
	Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_30);
	//4.创建IndexWriter对象
	IndexWriter indexWriter = new IndexWriter(directory, analyzer, maxFieldlength);
	//将document写入Lucene索引库
	indexWriter.addDocument(document);
	//5.关闭IndexWriter
	indexWriter.close();
}

这时候,就会在F:/Lucene的目录下创建相应的文件,如果没有这个文件夹,将会自动创建


这样,一个Lucene索引库就创建好了,接下来我们就来查询一下

public static void findIndexDB() throws Exception{
	//准备输入的值
	String keywords = "好";
	//创建Article对象的集合
	ArrayList<Article> arrayList = new ArrayList<Article>();
	//Lucene索引库的目录
	FSDirectory directory = FSDirectory.open(new File("F:/LuceneDB"));
	//采用的分词策略
	Version version = Version.LUCENE_30;
	Analyzer analyzer = new StandardAnalyzer(version);
	
	
	//1.创建IndexSearcher自符流对象
	IndexSearcher indexSearcher = new IndexSearcher(directory);
	//2.创建查询解析器
	/*
	 * 参数一: 使用分词器的版本
	 * 参数二: 对document的属性进行搜索
	 */
	QueryParser queryParser = new QueryParser(version,"xcontent", analyzer);
	//3.创建Query对象封装查询的关键字
	Query query = queryParser.parse(keywords);
	//根据关键字去索引里面搜索
	/*
	 * 参数一: 表示关键字查询对象,其他QueryParser表示查询器
	 * 参数二: MAX_RECORD表示如果根据关键字搜索出来的字段较多,只取前MAX_RECORD个内容,不足MAX_RECORD个的话,以实际为准
	 */
	int MAX_RECORD = 100;
	//使用indexSearcher查询前MAX_RECORD调记录
	TopDocs topDocs = indexSearcher.search(query, MAX_RECORD);
	//4.迭代出词汇表中符合条件的编号
	for (int i = 0; i < topDocs.scoreDocs.length; i++) {
		//取出封装编号和分数的ScoreDoc对象
		ScoreDoc scoreDoc = topDocs.scoreDocs[i];
		//取出每一个编号
		int no = scoreDoc.doc;
		//5.根据编号去原始记录表中查询对应的document对象
		Document document = indexSearcher.doc(no);
		//获取document的属性值
		String xid = document.get("xid");
		String xtitle = document.get("xtitle");
		String xcontent = document.get("xcontent");
		//6.封装到对象中
		Article article = new Article(Integer.parseInt(xid), xtitle, xcontent);
		//添加到集合中
		arrayList.add(article);
	}
	
	//遍历出来
	for (Article article : arrayList) {
		System.out.println("---------");
		System.out.println(article);
	}
	
	indexSearcher.close();
}

运行结果如下:








评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值