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的基本知识!

目录
相关文章
|
7月前
|
Java 索引
04Lucene入门程序
04Lucene入门程序
26 0
|
7月前
|
存储 自然语言处理 索引
05Lucene索引库的添加
05Lucene索引库的添加
16 0
|
存储 自然语言处理 算法
Lucene学习总结
Lucene学习总结
76 0
Lucene学习总结
|
存储 缓存 自然语言处理
Lucene存储结构(高级) | 学习笔记
快速学习Lucene存储结构(高级)。
650 0
Lucene存储结构(高级) | 学习笔记
|
自然语言处理 算法 数据库
lucene使用的一些注意事项 | 学习笔记
快速学习lucene使用的一些注意事项。
105 0
|
存储 人工智能 自然语言处理
看Lucene源码必须知道的基本概念
下面的一些基本概念不但有助于看源码,在使用像solr这样的搜索引擎框架的时候还可以知道自己的配置都做了些什么事情。我在定义这些概念的时候也都有自己的理解和思考。
看Lucene源码必须知道的基本概念
|
存储 自然语言处理 搜索推荐
MemoryIndex(一)(Lucene 8.8.0)
MemoryIndex(一)(Lucene 8.8.0)
406 0
MemoryIndex(一)(Lucene 8.8.0)
|
存储 索引 容器
ReaderPool(一)(Lucene 8.7.0)
ReaderPool(一)(Lucene 8.7.0)
196 0
|
调度 索引 容器
ReaderPool(二)(Lucene 8.7.0)
ReaderPool(二)(Lucene 8.7.0)
121 0
|
存储 自然语言处理 数据库
Lucene 查询原理
# 前言 Lucene 是一个基于 Java 的全文信息检索工具包,目前主流的搜索系统Elasticsearch和solr都是基于lucene的索引和搜索能力进行。想要理解搜索系统的实现原理,就需要深入lucene这一层,看看lucene是如何存储需要检索的数据,以及如何完成高效的数据检索。
8414 1