lucene为程序添加搜索功能,此功能基于已创建好的文档的索引之上。这里我已经为一些文档建立了索引,并保存到硬盘上。下面开始针对这些索引,添加搜索功能。
1、简单的TermQuery搜索
Java代码
/** * 【TermQuery方式搜索】 * * 对特定的项进行查询,如filename等于XPP3-LICENSE.txt的文件 * @throws Exception */ public void testTerm() throws Exception { Directory dir=FSDirectory.open(new File("d:/index/book_index/")); IndexSearcher searcher=new IndexSearcher(dir); Term t=new Term("content","params"); Query query=new TermQuery(t); TopDocs docs=searcher.search(query, 10); System.out.println(docs.totalHits+"--------"); t=new Term("filename","version"); docs=searcher.search(new TermQuery(t), 10); System.out.println(docs.totalHits); searcher.close(); dir.close(); }
2、使用QueryParser转化用户复杂输入,进行与或非查询操作。
Java代码
/** * 【QueryParser查询】 * * * 模糊查询,与,或,非方式 * @throws Exception */ public void testQueryParse() throws Exception{ Directory dir=FSDirectory.open(new File("d:/index/book_index/")); IndexSearcher search=new IndexSearcher(dir); QueryParser parser=new QueryParser(Version.LUCENE_30,"content",new SimpleAnalyzer()); Query query=parser.parse("+ADVISED +POSSIBILITY -JAVA"); TopDocs docs=search.search(query, 10); / assertEquals(1, docs.totalHits); Document document=search.doc(docs.scoreDocs[0].doc); System.out.println("查询第一个的名称"+document.get("filename")); System.out.println("与或非查询个数"+docs.totalHits); query=parser.parse("Indiana OR University"); docs=search.search(query, 10); System.out.println("Or查询个数"+docs.totalHits); search.close(); dir.close(); }
查询表达式 |
匹配文档 |
Java |
默认域包含有Java项的文档 |
Java junit Java OR junit |
默认域包含有Java,junit中一个,或者两个的文档 |
+Java +junit Java AND junit |
默认域同时包含有Java和junit的文档 |
Title:ant |
Title域中包含有ant的文档 |
Title:extreme -subject:sport Title:extreme AND NOT subject:sport |
Title域中包含extreme而且subject域中不包含sport |
(agile OR extreme) AND methody |
默认域包含有methody且包含agile或者extreme中的一个 |
Title:“junit in action” |
Title域一定为junit in action的文档 |
Title:“junit action“ -5 |
Title域中junit和action的间隔小于5的文档 |
Java* |
包含有Java开头的文档,如Javascript,Javaserver,Java等 |
Java~ |
包含与Java单词相近的文档,如Java |
Lastdate:[1/1/09 TO 12/31/09] |
Lastdate域在09年1月1号到09年12月31号的文档 |
3、近实时搜索
/** * 【近实时搜索】 * * @throws Exception */ public void testNRTsearch() throws Exception{ Directory dir=new RAMDirectory(); IndexWriter writer=new IndexWriter(dir, new StandardAnalyzer(Version.LUCENE_30), IndexWriter.MaxFieldLength.UNLIMITED); for (int i = 0; i < 10; i++) { Document doc=new Document(); doc.add(new Field("id", ""+i, Field.Store.NO, Field.Index.NOT_ANALYZED_NO_NORMS)); doc.add(new Field("text", "aaa", Field.Store.NO, Field.Index.ANALYZED )); writer.addDocument(doc); } IndexReader reader=writer.getReader(); IndexSearcher searcher=new IndexSearcher(reader); Query query=new TermQuery(new Term("text","aaa")); TopDocs docs=searcher.search(query, 1); System.out.println("[搜索的总数]"+docs.totalHits); //先删除id为7的文档,然后添加一个id为22的文档,进行搜索,看是不是近实时的 writer.deleteDocuments(new Term("id","7")); Document doc=new Document(); doc.add(new Field("id", "22", Field.Store.NO, Field.Index.NOT_ANALYZED_NO_NORMS)); doc.add(new Field("text","bbb",Field.Store.NO,Field.Index.ANALYZED)); writer.addDocument(doc); //重启reader,然后搜索 IndexReader newReader=reader.reopen(); assertEquals(reader==newReader,false); reader.close(); searcher=new IndexSearcher(newReader); TopDocs hits=searcher.search(query, 10); assertEquals(9, hits.totalHits); query=new TermQuery(new Term("text","bbb")); hits=searcher.search(query, 10); System.out.println("bbb文档的个数:"+hits.totalHits); //关闭资源 newReader.close(); writer.close(); }