Lucene的基本操作

简介: Lucene的基本操作

引言

 

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

 

第一、导入所需jar包



20170802205839530.png


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

 

第二、创建索引

  // 创建索引
  @Test
  public 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 这个路径是我需要搜索的文件所在的位置



20170802210358194.png


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

 

第三、搜索索引

      // 搜索索引
  @Test
  public 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("------------");
    }
  }

下面展示几种基本查询:

// 查询所有的资源
  @Test
  public void testMatchAllDocsQuery() throws Exception {
    IndexSearcher indexSearcher = getIndexSearcher();
    Query query = new MatchAllDocsQuery();
    System.out.println(query);
    printResult(indexSearcher, query);
    indexSearcher.getIndexReader().close();
  }
  // 根据数值范围查询
  @Test
  public 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();
  }
  // 组合条件查询
  @Test
  public 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();
  }
  // 条件查询
  @Test
  public 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();
  }
  // 条件解析的对象查询 多个默认域
  @Test
  public 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);
  }
// 根据条件删除
  @Test
  public void testDelete() throws Exception {
    IndexWriter indexWriter = getIndexWriter();
    Query query = new TermQuery(new Term("fileName", "lucene.txt"));
    indexWriter.deleteDocuments(query);
    indexWriter.close();
  }
  // 修改
  @Test
  public 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的基本知识!

目录
相关文章
|
网络安全 数据安全/隐私保护
【网络安全 | Crypto】hidden key 江苏工匠杯
【网络安全 | Crypto】hidden key 江苏工匠杯
367 0
【网络安全 | Crypto】hidden key 江苏工匠杯
|
12月前
|
前端开发
前端diff文件对比使用worker进行优化
如何使用Web Worker在React项目中优化文件对比差异功能的实现。
118 5
|
9月前
|
存储 人工智能 搜索推荐
2025年大品牌获胜的5大数字购物和客户体验趋势
2025年大品牌获胜的5大数字购物和客户体验趋势
|
负载均衡
网工配置命令基础总结(2)----VRRP配置
网工配置命令基础总结(2)----VRRP配置
972 0
|
JavaScript Java 测试技术
基于springboot+vue.js+uniapp的小区疫情防控附带文章源码部署视频讲解等
基于springboot+vue.js+uniapp的小区疫情防控附带文章源码部署视频讲解等
72 0
基于springboot+vue.js+uniapp的小区疫情防控附带文章源码部署视频讲解等
|
机器学习/深度学习 人工智能 iOS开发
探索iOS开发的未来:SwiftUI的革新之旅
在数字时代的浪潮中,iOS开发正经历一场由SwiftUI引领的变革。本文将深入探讨SwiftUI如何重塑移动应用开发,提升开发者的生产力,并展望其对iOS生态的影响。通过分析SwiftUI的核心特性、实际案例和未来趋势,我们将揭示这一现代框架如何定义用户体验的新标准,同时为iOS开发者指明技术进阶之路。
|
机器学习/深度学习 自然语言处理 Linux
稀疏微调:彻底改变大语言模型的推理速度
稀疏微调:彻底改变大语言模型的推理速度
609 0
|
JavaScript Java 测试技术
基于ssm+vue.js+uniapp小程序的新生报到系统附带文章和源代码部署视频讲解等
基于ssm+vue.js+uniapp小程序的新生报到系统附带文章和源代码部署视频讲解等
87 0
|
JavaScript API
vue中使用echarts动态循环渲染柱状图颜色
vue中使用echarts动态循环渲染柱状图颜色
627 0
|
存储 算法 Serverless
第六章:数组
第六章:数组
125 0