Lucene的基本操作

来源:互联网 发布:河南统计网络直报平台 编辑:程序博客网 时间:2024/05/29 13:23


   引言

   前面介绍了一些Lucene的基本知识,但是不用代码实现总是觉得不踏实,下面我们就完成Lucene的基本操作;

   第一、导入所需jar包

       

  上面jar包是本文中所用到的示例所需的jar包


  第二、创建索引

// 创建索引@Testpublic void testIndex() throws Exception {// 第一步:创建一个java工程,并导入jar包。// 第二步:创建一个indexwriter对象。Directory directory = FSDirectory.open(new File("D:\\temp\\index"));// 创建索引分析器Analyzer analyzer = new IKAnalyzer();// 官方推荐// 当项目中有多个lucene包的时候,需要在下面指定使用的版本IndexWriterConfig config = new IndexWriterConfig(Version.LATEST, analyzer);IndexWriter indexWriter = new IndexWriter(directory, config);// 1)指定索引库的存放位置Directory对象// 2)指定一个分析器,对文档内容进行分析。// 第三步:创建field对象,将field添加到document对象中。File f = new File("D:\\Lucene");// 获得路径下面的所有的文件File[] listFiles = f.listFiles();for (File file : listFiles) {// 第三步创建document对象Document document = new Document();String file_name = file.getName();// 创建域Field fileNameField = new TextField("fileName", file_name, Store.YES);long file_size = FileUtils.sizeOf(file);Field fileSizeField = new LongField("fileSize", file_size, Store.YES);// 文件路径String file_path = file.getPath();Field filePathField = new StoredField("filePath", file_path);// 文件内容String file_content = FileUtils.readFileToString(file);Field fileContentField = new TextField("fileContent", file_content, Store.NO);document.add(fileNameField);document.add(fileSizeField);document.add(filePathField);document.add(fileContentField);// 第四步 使用 indexwriter对象将docum对象写人索引库,此过程进行索引创建。并将索引和document对象写入索引库indexWriter.addDocument(document);}// 第五步: 关闭indexwriter对象indexWriter.close();}

  注意:D:\\temp\\index这个路径是 我们创建的索引存储的位置,如果此路径不存在,程序会自动创建

     D:\\Lucene 这个路径是我需要搜索的文件所在的位置

       

  我们可以通过lukeall-4.10.3.jar查看,请读者自行下载!


  第三、搜索索引

      // 搜索索引@Testpublic void testSearch() throws Exception {// 第一步:创建一个Directory对象,也就是索引库存放的位置。Directory directory = FSDirectory.open(new File("D:\\temp\\index"));// 第二步:创建一个indexReader对象,需要指定Directory对象。IndexReader indexReader = DirectoryReader.open(directory);// 第三步:创建一个indexsearcher对象,需要指定IndexReader对象IndexSearcher indexSearcher = new IndexSearcher(indexReader);// 第四步:创建一个TermQuery对象,指定查询的域和查询的关键词。Query query = new TermQuery(new Term("fileName", "quartz.txt"));// 第五步:执行查询。TopDocs topDocs = indexSearcher.search(query, 10);// 第六步:返回查询结果。遍历查询结果并输出。ScoreDoc[] scoreDocs = topDocs.scoreDocs;for (ScoreDoc scoreDoc : scoreDocs) {int doc = scoreDoc.doc;Document document = indexSearcher.doc(doc);// 文件名称String fileName = document.get("fileName");System.out.println(fileName);// 文件内容String fileContent = document.get("fileContent");System.out.println(fileContent);// 文件大小String fileSize = document.get("fileSize");System.out.println(fileSize);// 文件路径String filePath = document.get("filePath");System.out.println(filePath);System.out.println("------------");}indexReader.close();}

  这里需要注意:创建索引和搜索时所用的分词器必须一致(才能匹配)


   为了更好的展示我们的基本操作代码,我们讲创建indexSearcher对象的代码和查看查询结果的代码抽离

   

// 抽离创建indexSearcher对象的代码public IndexSearcher getIndexSearcher() throws Exception {Directory directory = FSDirectory.open(new File("D:\\temp\\index"));IndexReader indexReader = DirectoryReader.open(directory);return new IndexSearcher(indexReader);}// 抽离执行查询结果的代码public void printResult(IndexSearcher indexSearcher, Query query) throws Exception {// 第五步:执行查询。TopDocs topDocs = indexSearcher.search(query, 10);// 第六步:返回查询结果。遍历查询结果并输出。ScoreDoc[] scoreDocs = topDocs.scoreDocs;for (ScoreDoc scoreDoc : scoreDocs) {int doc = scoreDoc.doc;Document document = indexSearcher.doc(doc);// 文件名称String fileName = document.get("fileName");System.out.println(fileName);// 文件内容String fileContent = document.get("fileContent");System.out.println(fileContent);// 文件大小String fileSize = document.get("fileSize");System.out.println(fileSize);// 文件路径String filePath = document.get("filePath");System.out.println(filePath);System.out.println("------------");}}

  下面展示几种基本查询:

   

// 查询所有的资源@Testpublic void testMatchAllDocsQuery() throws Exception {IndexSearcher indexSearcher = getIndexSearcher();Query query = new MatchAllDocsQuery();System.out.println(query);printResult(indexSearcher, query);indexSearcher.getIndexReader().close();}// 根据数值范围查询@Testpublic void testNumericRangeQuery() throws Exception {IndexSearcher indexSearcher = getIndexSearcher();Query query = NumericRangeQuery.newLongRange("fileSize", 47L, 200L, false, true);System.out.println(query);printResult(indexSearcher, query);// 关闭资源indexSearcher.getIndexReader().close();}// 组合条件查询@Testpublic void testBooleanQuery() throws Exception {IndexSearcher indexSearcher = getIndexSearcher();BooleanQuery booleanQuery = new BooleanQuery();Query query1 = new TermQuery(new Term("fileName", "apache"));Query query2 = new TermQuery(new Term("fileName", "lucene"));booleanQuery.add(query1, Occur.MUST);booleanQuery.add(query2, Occur.SHOULD);printResult(indexSearcher, booleanQuery);// 关闭资源indexSearcher.getIndexReader().close();}// 条件查询@Testpublic void testQueryParser() throws Exception {IndexSearcher indexSearcher = getIndexSearcher();// 参数1:默认查询域// 参数2 采用分析器QueryParser queryParser = new QueryParser("fileName", new IKAnalyzer());// *:* 域:值Query query = queryParser.parse("fileName:paache AND fileName:lucene");printResult(indexSearcher, query);// 关闭资源indexSearcher.getIndexReader().close();}// 条件解析的对象查询 多个默认域@Testpublic void testMultiFieldQueryParser() throws Exception {IndexSearcher indexSearcher = getIndexSearcher();String[] fields = { "fileName", "fileContent" };// 参数1: 默认查询的域// 参数2:采用的分析器MultiFieldQueryParser queryParser = new MultiFieldQueryParser(fields, new IKAnalyzer());// *:* 域:值Query query = queryParser.parse("lucene is apache");printResult(indexSearcher, query);// 关闭资源indexSearcher.getIndexReader().close();}
 

  第四、删除和修改

   抽离创建IndexWriter对象的代码

public IndexWriter getIndexWriter() throws Exception {// 第一步:创建一个java工程,并导入jar包。// 第二步:创建一个indexwriter对象。Directory directory = FSDirectory.open(new File("D:\\temp\\index"));Analyzer analyzer = new StandardAnalyzer();// 官方推荐IndexWriterConfig config = new IndexWriterConfig(Version.LATEST, analyzer);return new IndexWriter(directory, config);}
 

  

// 根据条件删除@Testpublic void testDelete() throws Exception {IndexWriter indexWriter = getIndexWriter();Query query = new TermQuery(new Term("fileName", "lucene.txt"));indexWriter.deleteDocuments(query);indexWriter.close();}// 修改@Testpublic void testUpdate() throws Exception {IndexWriter indexWriter = getIndexWriter();Document doc = new Document();doc.add(new TextField("fileN", "测试文件名", Store.YES));doc.add(new TextField("fileC", "测试文件内容", Store.YES));indexWriter.updateDocument(new Term("fileName", "quartz.txt"), doc, new IKAnalyzer());indexWriter.close();}
  修改的本质就是增加,如果document存在则是修改的操作结果,若果document不存在则是增加的操作结果


   小结

   上面是基于Lucene的对应document的操作,我们可看出来这个的过程非常的麻烦,所以说如果我们在实际项中采用这个方案,会非常的影响开发效率,就好像我们采用原生servlet来开发java项目一样,所以这就需要一个框架来简化这个开发过程,于是solr就出现了。你说是“时势造英雄”呢?还是“英雄造时势”呢?下篇博客讲解solr的基本知识!