Lucene创建和查询索引库的HelloWorld(含详细注释)
来源:互联网 发布:淘宝优惠券小程序制作 编辑:程序博客网 时间:2024/05/24 06:22
本案例使用的是Lucene-3.6.2版本,Lucene官方网站:http://lucene.apache.org/。
案例说明:
本例模拟了贴吧中检索帖子的功能,通过创建Article类来模拟帖子对象。用户输入检索信息,Lucene就可以根据检索信息来获取与之相关的Article对象,并返回给用户。
一、建立工程
首先在我们的MyEclipse中创建一个Java工程即可,在里面创建一个lib文件夹用于存放我们开发时用的jar包。
二、导入jar包
本案例需要Lucene的4个基本jar包。如下:
lucene-core-3.6.2.jar
contrib\analyzers\common\lucene-analyzers-3.6.2.jar(分词器)
contrib\highlighter\lucene-highlighter-3.6.2.jar(高亮)
contrib\memory\lucene-memory-3.6.2.jar(高亮)
然后将lib中的四个jar包Build Path。三、创建HelloWorld类
在src下自创建一个包,并在包中创建HelloWorld.java文件。
这个文件中不需要main函数,我们将通过jUnit来测试程序。
所以在我们的方法中需要添加@Test注解。
public class HelloWorld {//创建索引库@Testpublic void createIndex() {}//搜索索引库@Testpublic void seacherIndex() {}}
四、创建检索类PO
创建我们需要检索的类Article(模拟帖子对象),里面有三个字段:id,title,content,
分别表示:编号、标题、内容。
public class Article {private Integer id;//idprivate String title;//标题private String 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;}@Overridepublic String toString() {return "Article [id=" + id + ", title=" + title + ", content="+ content + "]";}}
五、编写HelloWorld,实现创建和查询索引库
这里需要记住创建和查询的两个核心API:
向索引库中增删改的时候,使用IndexWriter对象。
其主要方法为:addDocument()、updateDocument()、deleteDocument()。
从索引库中搜索的时候,使用IndexSearcher对象。
其主要方法为:search()。里面的一些API的体系结构图会在最后的附件中列出,可对照查看。
程序中的步骤是按照编号走的,由于需要准备各种参数,所以显得有些凌乱,只要按照步骤参考即可。
import java.io.File;import java.io.IOException;import java.util.ArrayList;import java.util.List;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;import org.apache.lucene.document.Field.Index;import org.apache.lucene.document.Fieldable;import org.apache.lucene.document.Field.Store;import org.apache.lucene.index.CorruptIndexException;import org.apache.lucene.index.IndexReader;import org.apache.lucene.index.IndexWriter;import org.apache.lucene.index.IndexWriterConfig;import org.apache.lucene.queryParser.MultiFieldQueryParser;import org.apache.lucene.queryParser.QueryParser;import org.apache.lucene.search.IndexSearcher;import org.apache.lucene.search.Query;import org.apache.lucene.search.ScoreDoc;import org.apache.lucene.search.TopDocs;import org.apache.lucene.store.Directory;import org.apache.lucene.store.FSDirectory;import org.apache.lucene.store.LockObtainFailedException;import org.apache.lucene.util.Version;import org.junit.Test;import lucene.a_domain.Article;public class HelloWorld {//创建索引库/** * 执行这个方法会将这个方法中创建的Article对象中的属性:id,title,content转换成Document字段, * 索引库中只能存放Document类型对象,不能存放我们创建的对象,将Article转成Document后, * 通过IndexWriter的addDocument方法将转换后的Document对象添加到索引库中, * 执行这个方法后,将会在指定的索引库目录中创建索引文件,这是一堆二进制文件。 * 因为用到了IO,所以最后需要将IndexWriter关闭。 * @throws Exception */@Testpublic void createIndex() throws Exception {/* * 2.创建索引库目录,这是IndexWriter构造器的第一个参数。 * 这个Directory是个抽象类,按住ctrl+t可以查看这个类的继承体系, * 会发现他有一个子抽象类,叫做FSDirectory, * 我们需要使用这个类的实例当作我们的Directory, * 但他是抽象的,无法new, * FSDirectory里面有一个open方法, open方法接收一个File, * 这个open方法就可以获取FSDirectory实例, * 而File是我们指定的存放目录的路径,在当前工程创建一个indexDir文件夹作为路径即可, * 至此,索引库目录配置完成,将这个引用添加到IndexWriter的第一个参数的位置。 */Directory directory = FSDirectory.open(new File("./indexDir/"));/* * 4.创建IndexWriterConfig构造器的第二个参数,analyzer分词器。 * 这个Analyzer也是一个抽象类,ctrl+t查看其继承体系可以发现它有很多子类。 * 这里先使用它的标准分词器,StandardAnalyzer。 * new这个类需要一个版本号参数,同样通过Version的静态常量给出。 * 分词器创建完成。添加到IndexWriterConfig的第二个参数上。 */Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_36);/* * 3.创建IndexWriter构造器的第二个参数,配置。 * 直接new,发现报错,它的构造器需要两个参数, * 一个是Version,一个是Analyzer, * Version通过Version.LUCENE_36即可创建,这时Version类中的一个静态常量。 * Analyzer是分词器,这是Lucene自带的分词器,这个分词器不支持中文 */IndexWriterConfig indexWriterConfig = new IndexWriterConfig(Version.LUCENE_36,analyzer);//1.这里需要两个参数,第一个是索引库目录,第二个是配置,在上面提供这两个参数即可IndexWriter indexWriter = new IndexWriter(directory,indexWriterConfig);/* * 6.创建要存入索引库的对象Article, * 创建完成后,我们需要将Article中的属性转换成Document的字段 */Article article = new Article();article.setId(1);article.setTitle("Lucene是什么");article.setContent("Lucene,速度快捷方式离开减肥啦实际得分卡设计大方");/* * 7.将Article转换成Document对象, * 需要将Article中的属性转换成Document的字段 * 直接new一个Document,再通过Document的add方法添加字段, * add方法需要一个Fieldable类型的参数,Fieldable是一个接口, */Document doc = new Document();/* * 8.创建Fieldable的子类,ctrl+t查看继承体系,发现有个Field子类 * 创建Field需要四个参数,String name,String value,Store store,Index index * 第一个参数表示索引库的字段名称; * 第二个参数表示存放到该字段上的值; * 第三个参数表示是否存储 * 第四个参数表示分词 * 在add方法里直接new,Article有三个属性,需要添加三个字段到Document中,所以add三次 *///Fieldable field = new Field("id",article.getId().toString(),Store.YES,Index.ANALYZED);doc.add(new Field("id",article.getId().toString(),Store.YES,Index.ANALYZED));doc.add(new Field("title", article.getTitle(), Store.YES, Index.ANALYZED));doc.add(new Field("content", article.getContent(), Store.YES, Index.ANALYZED));/* * 5.创建索引库,使用IndexWriter的addDocument方法。 * 这个方法需要一个Document参数。这个Document就是放入索引库的数据, * 但是我们需要放入的是Article对象,这就需要将我们的Article类型转换成Document类型。 */indexWriter.addDocument(doc);/* * 9.关闭流 */indexWriter.close();}//搜索索引库/** * 搜索索引库时,开始先创建了一个List集合来存储最终查询的结果。 * 这个程序中,将查询条件写死了,真正开发的时候是不可能写死的,所以开发时这个查询条件是需要获取的。 * 根据查询条件就可以从索引库的到最终的结果集,但是索引库中存放的是Document对象,所以获取的结果集也是Document对象集合。 * 还需要将Document对象转换成我们需要的Article对象,根据document对象的get方法获取即可,get(name)参数为字段名称。 * 最后我们调用了showResults(List list)方法将获取的结果集遍历取出,显示在控制台上。 * @throws Exception */@Testpublic void seacherIndex() throws Exception {//创建一个集合,存放查询出来的数据。List<Article> list = new ArrayList<Article>();/* * 2.创建索引库目录,指定索引库目录路径,提供给IndexSearcher */Directory directory = FSDirectory.open(new File("./indexDir/"));/* * 1.创建IndexSearcher对象,这个对象的构造器需要接收一个IndexReader对象 * 这个IndexReader是一个抽象类,它里面有一个抽象方法:open。 * open方法的参数是Directory,即索引库目录,需要指定它从那个索引库目录中读取数据。 * 在上面创建这个目录,跳到第2步。 */IndexSearcher indexSearcher = new IndexSearcher(IndexReader.open(directory));/* * 4.创建查询条件 * QueryParser只能指定在一个字段上进行检索,例如如果指定了id字段就只能查询id字段。是单字段检索。 * QueryParser有三个参数, * 参数1:版本 * 参数2:表示对哪个字段进行检索,这里传入一个字段名称 * 参数3:分词器 * 这里查询条件是"Lucene"表示在某个字段中查询"Lucene"。 */String queryString = "Lucene";//6.准备分词器:Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_36);//5.创建解析器QueryParser queryParser = new QueryParser(Version.LUCENE_36,"title",analyzer);//7.将查询条件放入解析器中。这里返回的是query对象,这个对象作为IndexSearcher的search方法的第一个参数Query query = queryParser.parse(queryString);/* * 3.通过IndexSearcher的search方法创建查询 * 参数1:表示查询条件 * 参数2:表示返回的前多少条记录 * search返回值为TopDocs类型,这是查询完的结果集。 */TopDocs topDocs = indexSearcher.search(query, 100);System.out.println("总记录数:" + topDocs.totalHits);//这个字段获取查询到的总记录数。//8.获取结果集数组ScoreDoc[] scoreDocs = topDocs.scoreDocs;//遍历scoreDocs,if(scoreDocs!=null && scoreDocs.length>0) {for (int i = 0; i < scoreDocs.length; i++) {ScoreDoc scoreDoc = scoreDocs[i];System.out.println("获取这个记录的得分:" + scoreDoc.score);//获取检索出的记录在索引库中的唯一编号,根据这个编号就可以获取需要的数据int doc = scoreDoc.doc;//IndexSearcher的doc方法可以通过刚获取的唯一编号从索引库中获取我们需要的数据Document document = indexSearcher.doc(doc);//获取了Document对象,还需要将Document对象转成Article对象。Article article = new Article();/* * 通过document对象的get方法,根据字段名称获取值, * 这里的名称是通过上面的 * doc.add(new Field("id",article.getId().toString(),Store.YES,Index.ANALYZED)); * 这个方法设置的字段名称 */article.setId(Integer.parseInt(document.get("id")));article.setTitle(document.get("title"));article.setContent(document.get("content"));//添加到存放结果的集合中。list.add(article);}}//9.关闭流indexSearcher.close();//10.遍历输出最终获取的结果集合if(list != null && list.size() > 0) {showResults(list);}}private void showResults(List<Article> list) {for(Article article : list) {System.out.println("文章编号:" + article.getId());System.out.println("文章标题:" + article.getTitle());System.out.println("文章内容:" + article.getContent());System.out.println("------------------------------------------------");}}}先执行createIndex方法,这样我们先建立的索引库就有数据了,然后再执行seacherIndex方法,就可以将索引库获取的数据显示在控制台上。
六、查看索引库中生成的文件
我们将索引库定义在了工程的根目录下:
进入这个目录,可以看到生成的文件,这都是一些二进制文件。
七、附件
这里提供了一些类的继承体系信息。
Directory类:
Analyzer类:
- Lucene创建和查询索引库的HelloWorld(含详细注释)
- lucene 索引创建查询
- solr入门之lucene创建索引和查询索引及查询的源码读取类确定
- Lucene的创建和查询
- 【Lucene】使用反射技术优化Lucene索引库的查询与创建
- Lucene的入门例子 - 创建索引,利用索引查询
- lucene创建索引,分组查询
- lucene 创建索引 查询实例
- lucene(索引的查询)
- lucene--索引的创建
- Lucene 查询索引库
- java鬼混笔记:lucene 1、简单的创建索引和查询
- Lucene创建索引和索引的基本检索
- Lucene索引的详细结构
- lucene索引创建与查询入门例子
- Lucene索引创建、查询与高亮
- Lucene简单实现创建索引以及查询
- Lucene创建、查询、删除、更新 索引
- Confluence 修改历史(Change-History)宏
- Java那些事儿之线程安全
- 特殊四位数
- 再熟悉一下Eclipse快捷键
- 【20140206】曼昆著《经济学原理》读书笔记
- Lucene创建和查询索引库的HelloWorld(含详细注释)
- USACO月赛题解 第四讲 贪心
- java学习之面试题5
- unity3d笔记(5)——调用Webcam设备
- Palindrome Partitioning
- jar not loaded. See Servlet Spec 2.3, section 9.7.2.
- DButils的使用感受
- ajax请求中遇到的中文字符编码问题
- java网络唤醒,win7的网络唤醒(后面更新Liunx的)