搜索的一般步骤:
1、创建IndexReader
2、使用IndexReader创建IndexSearcher
3、根据搜索关键字,使用QueryParser生成Query对象
4、以Query作为参数调用IndexSearcher.search(),执行搜索
5、以TopDocs以及ScoreDocs遍历结果并处理
这里主要涉及的类有:IndexSearcher(执行search()方法的类)、IndexReader(对索引文件进行读操作,并为IndexSearcher提供搜索接口)、Query及其子类(查询对象,search()方法的重要参数)、QueryParser(根据用户输入的搜索词汇生成Query对象)、TopDocs(search()方法返回的前n个文档)、ScoreDocs(提供TopDocs中搜索结果的访问接口)。
1、创建IndexReader
创建IndexReader是通过调用DirectoryReader.open()方法,接收的是一个Directory参数,示例代码如下:
1 |
IndexReader reader = DirectoryReader.open(FSDirectory.open(new File(indexStorePath))); |
创建IndexReader需要很大的开销,因此最好在整个搜索中都重复使用一个IndexReader,只有在必要的时候才创建新的IndexReader。
在创建IndexReader时,它会搜索已有的索引快照,如果你需要搜索索引中的变更信息,那么必须打开一个新的reader。IndexReader的openIfChanged()方法可以判断如果索引信息有变更,可以在耗费较少系统资源的情况下重新创建IndexReader。
2、创建IndexSearcher
IndexSearcher的创建比较简单,一个构造函数,接收一个IndexReader作为参数即可。
3、创建QueryParser及Query
1 2 3 4 |
Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_4_9); QueryParser parser = new QueryParser(Version.LUCENE_4_9, field, analyzer); // 将关键字包装成Query对象 Query query = parser.parse(keyword); |
这里的field,就是一个字符串,说明建立索引的时候存储的是那个field(与建立索引时的field的name一致)。
另外还有一种方式生成Query对象,代码如下:
1 2 |
Term term= new Term(field, keyword); TermQuery tq = new TermQuery(term); |
当然使用这样的代码是没有办法实现搜索的,以为TermQuery适用于完全匹配的搜索,如搜索id号,二维码,姓名等,我们这里的关键词搜索没有办法使用这个。具体的这个类有哪些实现我们之后还会详细介绍。
4、Query作为参数执行搜索
1 |
TopDocs results = searcher.search(query, 10); |
这就是很简单的一个方法调用,执行搜索操作。返回的即是搜索的结果。这里10的意思是查找Top10。
5、遍历结果
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
ScoreDoc[] h = results.scoreDocs; if (h.length == 0) { System.out.println("对不起,没有找到您要的结果。"); } else { for (int i = 0; i < h.length; i++) { try { Document doc = searcher.doc(h[i].doc); System.out.print("这是第" + i + "个检索到的结果,文件名为:"); System.out.println(doc.get("path")); System.out.println("doc: " + h[i].doc + ", score: " + h[i].score); } catch (Exception e) { e.printStackTrace(); } } } System.out.println("--------------------------"); |
这里的doc.get("path")即是我们在创建索引的时候,设置的一个域,名称叫path,但是我们的content默认设定为未存储,所以如果doc.get("content")会返回null。一般文件内容都不需要存储,我们可以通过文件路径把文件内容直接呈现出来,这样可以节省索引的空间。
详细代码见github:
https://github.com/irfen/lucene-example
本文发表自赵伊凡BLOG
©原创文章,转载请注明来源: 赵伊凡's Blog
©本文链接地址: 4、Lucene4.9学习笔记——Lucene搜索的使用
“4、Lucene4.9学习笔记——Lucene搜索的使用”的35个回复