lucene的简易入门(创建索引,搜索)

2016年05月27日 原创
关键词: java lucene
摘要 Lucene是apache软件基金会4 jakarta项目组的一个子项目,是一个开放源代码的全文检索引擎工具包,但它不是一个完整的全文检索引擎,而是一个全文检索引擎的架构,提供了完整的查询引擎和索引引擎。本文介绍了如何使用lucene来创建索引和检索。

Lucene是apache软件基金会4 jakarta项目组的一个子项目,是一个开放源代码的全文检索引擎工具包,但它不是一个完整的全文检索引擎,而是一个全文检索引擎的架构,提供了完整的查询引擎和索引引擎,部分文本分析引擎(英文与德文两种西方语言)。Lucene的目的是为软件开发人员提供一个简单易用的工具包,以方便的在目标系统中实现全文检索的功能,或者是以此为基础建立起完整的全文检索引擎。Lucene是一套用于全文检索和搜寻的开源程式库,由Apache软件基金会支持和提供。Lucene提供了一个简单却强大的应用程式接口,能够做全文索引和搜寻。在Java开发环境里Lucene是一个成熟的免费开源工具。就其本身而言,Lucene是当前以及最近几年最受欢迎的免费Java信息检索程序库。

创建索引

public void testCreateIndex() {
		//准备数据
		try {
			//一个document就是一个数据存储对象
			Document doc = new Document();
			doc.add(new TextField("title","MySQL索引对数据库查询速度的显著提升",Store.YES));
			doc.add(new TextField("content","索引用于快速找出在某个列中有一特定值的行。不使用索引,MySQL必须从第1条记录开始然后读完整个表直到找出相关的行。表越大,花费的时间越多。如果表中查询的列有一个索引,MySQL能快速到达一个位置去搜寻到数据文件的中间,没有必要看所有数据。如果一个表有1000行,这比顺序读取至少快100倍。注意如果你需要访问大部分行,顺序读取要快得多,因为此时我们避免磁盘搜索。大多数MySQL索引(PRIMARY KEY、UNIQUE、INDEX和FULLTEXT)在B树中存储。只是空间列类型的索引使用R-树,并且MEMORY表还支持hash索引。",Store.YES));
			doc.add(new StringField("id","1",Store.YES));
			Document doc1 = new Document();
			doc1.add(new TextField("title","Go Through算法导论:桶排序",Store.YES));
			doc1.add(new TextField("content","通排序(bucket sort)假设输入数据服从均匀分布,平均情况下它的时间代价为O(n)。与计数排序类似,因为对输入数据作了某种假设,通排序的速度也很快。具体来说,计数排序假设输入数据都属于一个小区间内的整数,而桶排序则假设输入是由一个随机过程产生,该过程将元素均匀、独立地分布在[0,1)区间上。通排序将[0,1]区间划分为n个相同大小的子区间,或称为桶。然后,将n个输入数分别放到各个桶中。因为输入数据是均匀、独立地分布在[0,1]区间上,所以一般不会出现很多数落在同一个桶中的情况。为了得到输出结果,我们先对每个桶中的数进行排序,然后遍历每个桶,按照次序把各个桶中的元素列出来即可。在桶排序的代码中,我们假设输入是一个包含n个元素的数组A,且每个元素A[i]满足0≤A[i]≤1。此外,算法还需要一个临时数组B[0..n-1]来存放链表(即桶),并假设存在一种用于维护这些链表的机制。下面是桶排序的伪代码",Store.YES));
			doc1.add(new StringField("id","2",Store.YES));
			//Directory就是存储索引的目录
			Directory dir = FSDirectory.open(new File("myindex").toPath());
			//使用标准分词器
			StandardAnalyzer analyzer = new StandardAnalyzer();
			IndexWriterConfig config = new IndexWriterConfig(analyzer);
			IndexWriter writer = new IndexWriter(dir, config);
			//创建索引
			writer.addDocument(doc);
			writer.addDocument(doc1);
			writer.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

检索

public void testSearch() {
		try {
			//搜索内容
			String queryStr = "排序";
			//搜索哪个索引库
			IndexReader reader = DirectoryReader.open(FSDirectory.open(new File("myindex").toPath()));
			IndexSearcher searcher = new IndexSearcher(reader);
			//新建一个查询,在内容中查询,对搜索内容使用标准分词器分词
			Query q = QueryParserUtil.parse( new String[]{queryStr},new String[]{"content"},new StandardAnalyzer());
			//创建一个“前10名”的集合
			TopScoreDocCollector collector = TopScoreDocCollector.create(10);
			//把搜索结果放在集合中
			searcher.search(q, collector);
			ScoreDoc[] scoreDocs = collector.topDocs().scoreDocs;
			//打印结果
			for (ScoreDoc scoreDoc : scoreDocs) {
				int docID = scoreDoc.doc;
				Document doc = searcher.doc(docID);
				System.out.println(doc.get("id"));
				System.out.println(doc.get("title"));
				System.out.println(doc.get("content"));
				System.out.println("---------------------");
			}
		} catch (IOException e) {
			e.printStackTrace();
		} catch (QueryNodeException e) {
			e.printStackTrace();
		}
	}