lucene
lucene 版本与jdk版本匹配:
昆明IT培训的老师知道Lucene,最新版是Lucene6.2.1,匹配的jdk版本是1.8正式版。
这里用jdk7最后一版,所以用Lucene5.3.3。引用的jar包有: lucene-core-5.5.5.jar、lucene-queryparser-5.5.5.jar、lucene-analyzers-smartcn-5.5.5.jar、lucene-analyzers-common-5.5.5.jar、commons-io-2.5.jar
一: 创建索引: 索引可以保存在内存和硬盘上,本例中把索引文件放到硬盘上。步骤: 1、指定保存索引的目录;2、创建 IndexWrier 对象 ;3、创建Document对象,相当于数据库表; 4、为Document 添加Field (Field 相当于表的字段);5; 通过IndexWriter 添加文档到索引目录中。 即把表信息写入到指定的目录中。代码如下:
public void index() { IndexWriter writer = null; try { //1、创建Directory , 即索引文件在硬盘上保存的目录 Path path = Paths.get("E:/myexe/luceneTest01/index01"); Directory directory = FSDirectory.open(path); //2、创建 IndexWriter , 通过 IndexWriter 把 Document 写入到硬盘中。 IndexWriterConfig iwc = new IndexWriterConfig(new StandardAnalyzer()); writer = new IndexWriter(directory, iwc); //在写入前需要先删除以前的索引文件。否则会重复。 writer.deleteAll(); //3、创建Document 对象,类似数据库表。 Document doc = null; //4、读取指定目录下所有的源文件,把这些文件的 内容,文件名,文件路径作为Document表的 Field。 File f= new File("E:/myexe/luceneTest01/example/"); for(File file:f.listFiles()) { doc = new Document(); doc.add(new TextField("content",new FileReader(file))); doc.add(new TextField("filename",file.getName(),Field.Store.YES)); doc.add(new TextField("path", file.getAbsolutePath(),Field.Store.YES)); // 5、通过IndexWriter 把Document 写入到索引文件中,索引文件保存在指定的 Directory 目录。 writer.addDocument(doc); } } catch (CorruptIndexException e) { e.printStackTrace(); } catch (LockObtainFailedException e) { e.printStackTrace(); } catch(IOException e) { e.printStackTrace(); } finally { try{ if (writer != null) { //关闭IndexWriter writer.close(); } } catch (CorruptIndexException e) { e.printStackTrace(); } catch(IOException e) { e.printStackTrace(); } } }
Field.Store.YES 设置为YES 表示把这个域中的内容完全存储到索引文件中,方便进行文本的还原。 为NO 表示把域的内容不存储到文件中,但可以被索引。
二: 搜索
public void searcher() { try { //1、创建 Directory , 指定搜索的 索引目录 Path path = Paths.get("E:/myexe/luceneTest01/index01"); Directory directory = FSDirectory.open(path); //2、创建IndexReader, IndexReader读取上面的 Directory IndexReader reader = DirectoryReader.open(directory); //3、根据IndexReader 创建IndexSearcher IndexSearcher searcher = new IndexSearcher(reader); //4、创建搜索的Query,即相当于sql语句 //指定所有域是 content,即在创建索引时保存的 content 域 QueryParser parser = new QueryParser("content", new StandardAnalyzer()); //搜索域 content 中包含 package 的文档 Query query = parser.parse("package"); //5、根据IndexSearcher 搜索,并返回 TopDocs //第一个参数是搜索的条件,第二个参数是返回10条结果 TopDocs tds = searcher.search(query, 10); //6、搜索的内容保存在 TopDocs 对象的 ScoreDoc对象 数组中。 ScoreDoc[] sds = tds.scoreDocs; for(ScoreDoc sd:sds) { //7、ScoreDoc 数组中元素的 doc 属性就是 搜索的 Document 对象 Document d = searcher.doc(sd.doc); //8、获取 Document 的文件名、文件路径、文件内容 System.out.println(d.get("filename") + " [" + d.get("path") + "] " + d.get("content")); System.out.println(d.get("content")); } //9、关闭reader reader.close(); } catch (CorruptIndexException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (ParseException e) { e.printStackTrace(); } }
输出 在E:\myexe\luceneTest01\example\ 目录下的所有文件中包含 package 单词的内容。因为 content 在创建索引时,没有保存在索引文件中,所以 content 域是 null (因为文件内容 content 一般比较大,在创建索引是
doc.add(new TextField("content",new FileReader(file))); 没有把文件内容保存在 索引中) :
PagerAppoint.java [E:\myexe\luceneTest01\example\PagerAppoint.java] null
null
App.txt [E:\myexe\luceneTest01\example\App.txt] null
null