需求
实现一个文件的搜索功能,通过关键字搜索文件,凡是文件名或文件内容包括关键字的文件都需要找出来。还可以根据中文词语进行查询,并且需要支持多个条件查询。
本案例中的原始内容就是磁盘上的文件,如下图:
使用indexwriter对象创建索引
创建索引
1.实现步骤
- 第一步:创建一个java工程,并导入jar包。
- 第二步:创建一个indexwriter对象。
1)指定索引库的存放位置Directory对象
2)指定一个分析器,对文档内容进行分析。 - 第二步:创建document对象。
- 第三步:创建field对象,将field添加到document对象中。
- 第四步:使用indexwriter对象将document对象写入索引库,此过程进行索引创建。并将索引和document对象写入索引库。
- 第五步:关闭IndexWriter对象。
2.代码实现
//指定索引库存放的路径 //D:\temp\0108\index Directory directory = FSDirectory.open(new File("D:\\indexfile")); //索引库还可以存放到内存中 //Directory directory = new RAMDirectory(); //创建一个标准分析器 Analyzer analyzer = new StandardAnalyzer(); //创建indexwriterCofig对象 //第一个参数: Lucene的版本信息,可以选择对应的lucene版本也可以使用LATEST //第二根参数:分析器对象 IndexWriterConfig config = new IndexWriterConfig(Version.LATEST, analyzer); //创建indexwriter对象 IndexWriter indexWriter = new IndexWriter(directory, config); //原始文档的路径D:\传智播客\01.课程\04.lucene\01.参考资料\searchsource File dir = new File("D:\\lunce_test"); for (File f : dir.listFiles()) { //文件名 String fileName = f.getName(); //文件内容 String fileContent = FileUtils.readFileToString(f); //文件路径 String filePath = f.getPath(); //文件的大小 long fileSize = FileUtils.sizeOf(f); //创建文件名域 //第一个参数:域的名称 //第二个参数:域的内容 //第三个参数:是否存储 Field fileNameField = new TextField("filename", fileName, Field.Store.YES); //文件内容域 Field fileContentField = new TextField("content", fileContent, Field.Store.YES); //文件路径域(不分析、不索引、只存储) Field filePathField = new TextField("path", new FileReader(filePath)); //文件大小域 Field fileSizeField = new TextField("size", fileSize + "", Field.Store.YES); //创建document对象 Document document = new Document(); document.add(fileNameField); document.add(fileContentField); document.add(filePathField); document.add(fileSizeField); //创建索引,并写入索引库 indexWriter.addDocument(document); } //关闭indexwriter indexWriter.close();
运行程序后,打开indexfile文件夹会发现有如下文件:
3.使用Luke工具查看索引文件
使用命令:java -jar lukeall-4.10.3.jar
查询索引
1.实现步骤
第一步:创建一个Directory对象,也就是索引库存放的位置。
第二步:创建一个indexReader对象,需要指定Directory对象。
第三步:创建一个indexsearcher对象,需要指定IndexReader对象
第四步:创建一个TermQuery对象,指定查询的域和查询的关键词。
第五步:执行查询。
第六步:返回查询结果。遍历查询结果并输出。
第七步:关闭IndexReader对象
2.代码实现
//指定索引库存放的路径 //D:\temp\0108\index Directory directory = FSDirectory.open(new File("D:\\indexfile")); //创建indexReader对象 IndexReader indexReader = DirectoryReader.open(directory); //创建indexsearcher对象 IndexSearcher indexSearcher = new IndexSearcher(indexReader); //创建查询 Query query = new TermQuery(new Term("content", "people")); //执行查询 //第一个参数是查询对象,第二个参数是查询结果返回的最大值 TopDocs topDocs = indexSearcher.search(query, 10); //查询结果的总条数 System.out.println("查询结果的总条数:"+ topDocs.totalHits); //遍历查询结果 //topDocs.scoreDocs存储了document对象的id for (ScoreDoc scoreDoc : topDocs.scoreDocs) { //scoreDoc.doc属性就是document对象的id //根据document的id找到document对象 Document document = indexSearcher.doc(scoreDoc.doc); System.out.println(document.get("filename")); //System.out.println(document.get("content")); System.out.println(document.get("path")); System.out.println(document.get("size")); } //关闭indexreader对象 indexReader.close();
运行结果:
3.TopDocs
Lucene搜索结果可通过TopDocs遍历,TopDocs类提供了少量的属性,如下:
注意:
Search方法需要指定匹配记录数量n:indexSearcher.search(query, n)
TopDocs.totalHits:是匹配索引库中所有记录的数量
TopDocs.scoreDocs:匹配相关度高的前边记录数组,scoreDocs的长度小于等于search方法指定的参数n