从01开始 从01开始
首页
  • 计算机科学导论
  • 数字电路
  • 计算机组成原理

    • 计算机组成原理-北大网课
  • 操作系统
  • Linux
  • Docker
  • 计算机网络
  • 计算机常识
  • Git
  • JavaSE
  • Java高级
  • JavaEE

    • Ant
    • Maven
    • Log4j
    • Junit
    • JDBC
    • XML-JSON
  • JavaWeb

    • 服务器软件
    • Servlet
  • Spring
  • 主流框架

    • Redis
    • Mybatis
    • Lucene
    • Elasticsearch
    • RabbitMQ
    • MyCat
    • Lombok
  • SpringMVC
  • SpringBoot
  • 学习网课的心得
  • 输入法
  • 节假日TodoList
  • 其他
  • 关于本站
  • 网站日记
  • 友人帐
  • 如何搭建一个博客
GitHub (opens new window)

peterjxl

人生如逆旅,我亦是行人
首页
  • 计算机科学导论
  • 数字电路
  • 计算机组成原理

    • 计算机组成原理-北大网课
  • 操作系统
  • Linux
  • Docker
  • 计算机网络
  • 计算机常识
  • Git
  • JavaSE
  • Java高级
  • JavaEE

    • Ant
    • Maven
    • Log4j
    • Junit
    • JDBC
    • XML-JSON
  • JavaWeb

    • 服务器软件
    • Servlet
  • Spring
  • 主流框架

    • Redis
    • Mybatis
    • Lucene
    • Elasticsearch
    • RabbitMQ
    • MyCat
    • Lombok
  • SpringMVC
  • SpringBoot
  • 学习网课的心得
  • 输入法
  • 节假日TodoList
  • 其他
  • 关于本站
  • 网站日记
  • 友人帐
  • 如何搭建一个博客
GitHub (opens new window)
  • JavaSE

  • JavaSenior

  • JavaEE

  • JavaWeb

  • Spring

  • 主流框架

    • Redis

    • Mybatis

    • Lucene

      • 全文检索的概念
      • Lucene概述
      • Lucene入门案例
      • 分析器
      • 常见的Field
      • 索引库的维护
      • Lucene索引库查询
        • TermQuery:关键词查询
        • newRangeQuery 数值范围查询
        • 使用queryparser查询
        • 总结
      • Lucene
    • Elasticsearch

    • MQ

    • MyCat

    • Lombok

    • 主流框架
  • SpringMVC

  • SpringBoot

  • Java并发

  • Java源码

  • JVM

  • 韩顺平

  • Java
  • Java
  • 主流框架
  • Lucene
2023-05-16
目录

Lucene索引库查询

# 50.Lucene索引库查询

对要搜索的信息创建Query查询对象,Lucene会根据Query查询对象生成最终的查询语法,类似关系数据库SQL语法一样,Lucene也有自己的查询语法,比如:"name:lucene"表示查询 Field 的 name为 "lucene" 的文档信息。   ‍

可通过两种方法创建查询对象:

  • 使用Lucene提供的Query子类
  • 使用QueryParse解析查询表达式

‍

# TermQuery:关键词查询

TermQuery,通过项查询,TermQuery不使用分析器。所以建议匹配不分词的Field域查询,比如订单号、分类ID号等。

构造方法里指定要查询的域和要查询的关键词,相关演示已经在searchIndex方法中演示过了:

@Test
public void searchIndex() throws Exception {
    Directory directory = FSDirectory.open(new File("D:\\temp\\index").toPath());
    IndexReader indexReader = DirectoryReader.open(directory);
    IndexSearcher indexSearcher = new IndexSearcher(indexReader);
    Query query = new TermQuery(new Term("name", "spring"));

    TopDocs topDocs = indexSearcher.search(query, 10);
    System.out.println("查询出来的总记录数:" + topDocs.totalHits);

    // 6. 第六步:返回查询结果。遍历查询结果并输出。
    ScoreDoc[] scoreDocs = topDocs.scoreDocs;
    for (ScoreDoc scoreDoc : scoreDocs) {
        int docId = scoreDoc.doc;
        // 根据id取文档对象
        Document document = indexSearcher.doc(docId);
        // 取文档的属性
        System.out.println("name: " + document.get("name"));
        System.out.println("path: " + document.get("path"));
        System.out.println("size: " + document.get("size"));
        //System.out.println("content: " + document.get("content"));
        System.out.println("-------------分割线-----------------");
    }

    // 7. 第七步:关闭IndexReader对象
    indexReader.close();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

‍

‍

‍

# newRangeQuery 数值范围查询

假设查询文件大小在0 ~ 100之间的:

@Test
public void testRangeQuery() throws Exception {
    // 创建一个Query对象
    Query query = LongPoint.newRangeQuery("size", 0L, 100L);

    // 执行查询
    TopDocs topDocs = indexSearcher.search(query, 10);

    System.out.println("总记录数: " + topDocs.totalHits);

    ScoreDoc[] scoreDocs = topDocs.scoreDocs;
    for (ScoreDoc scoreDoc : scoreDocs) {
        int docId = scoreDoc.doc;
        System.out.println("文档id: " + docId);
        System.out.println("文档得分: " + scoreDoc.score);
        Document document = indexSearcher.doc(docId);
        System.out.println("name: " + document.get("name"));
        System.out.println("path: " + document.get("path"));
        System.out.println("size: " + document.get("size"));
        System.out.println("content: " + document.get("content"));
        System.out.println("-------------分割线-----------------");
    }

    indexReader.close();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

‍

运行结果:

总记录数: 3
文档id: 0
文档得分: 1.0
name: 1.create web page.txt
path: D:\temp\searchsource\1.create web page.txt
size: 47
content: Learn how to create a web page with Spring MVC.
-------------分割线-----------------
文档id: 1
文档得分: 1.0
name: 2.Serving Web Content.txt
path: D:\temp\searchsource\2.Serving Web Content.txt
size: 35
content: Serving Web Content with Spring MVC
-------------分割线-----------------
文档id: 8
文档得分: 1.0
name: spring.txt
path: D:\temp\searchsource\spring.txt
size: 82
content: The Spring Framework provides a comprehensive programming and configuration model.
-------------分割线-----------------
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

‍

# 使用queryparser查询

例如我们要查询一句话,而不是一个词;但TermQuery是根据关键词查询的,所以用它来查询一句话是查不到的。我们先将这句话分词,然后搜索,这就是queryparser。

通过QueryParser也可以创建Query,QueryParser提供一个Parse方法,此方法可以直接根据查询语法来查询。Query对象执行的查询语法可通过System.out.println(query);​查询。

因为要分词,所以需要用到分析器。建议创建索引时使用的分析器和查询索引时使用的分析器要一致。

我们之前已经引入过依赖了:

<dependency>
  <groupId>org.apache.lucene</groupId>
  <artifactId>lucene-queryparser</artifactId>
  <version>7.4.0</version>
</dependency>
1
2
3
4
5

‍

‍

在查询之前,我们还是先重建索引,这里我们用createIndexWithIK​方法重建

‍

写个方法演示:

@Test
public void testQueryParser() throws Exception{
    // 创建一个QueryParser对象,需要两个参数,参数1:默认搜索域   参数2:分析器对象
    QueryParser queryParser = new QueryParser("name", new IKAnalyzer());

    Query query = queryParser.parse("lucene是一个Java开发的全文检索工具包");

    // 执行查询
    TopDocs topDocs = indexSearcher.search(query, 10);
    System.out.println("总记录数: " + topDocs.totalHits);

    ScoreDoc[] scoreDocs = topDocs.scoreDocs;
    for (ScoreDoc scoreDoc : scoreDocs) {
        int docId = scoreDoc.doc;
        System.out.println("文档id: " + docId);
        System.out.println("文档得分: " + scoreDoc.score);
        Document document = indexSearcher.doc(docId);
        System.out.println("name: " + document.get("name"));
        System.out.println("path: " + document.get("path"));
        System.out.println("size: " + document.get("size"));
        System.out.println("-------------分割线-----------------");
    }

    indexReader.close();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

‍

运行结果:可以看到我们搜索的是一句话,但是也能根据分词后的结果搜索

加载扩展词典:hotword.dic
加载扩展停止词典:stopword.dic
总记录数: 4
文档id: 13
文档得分: 5.277659
name: 全文检索.txt
path: D:\temp\searchsource\全文检索.txt
size: 1691
-------------分割线-----------------
文档id: 2
文档得分: 1.5057791
name: apache lucene.txt
path: D:\temp\searchsource\apache lucene.txt
size: 725
-------------分割线-----------------
文档id: 5
文档得分: 1.5057791
name: lucene_changs.txt
path: D:\temp\searchsource\lucene_changs.txt
size: 501873
-------------分割线-----------------
文档id: 3
文档得分: 1.3724493
name: Apache_Lucene_README.txt
path: D:\temp\searchsource\Apache_Lucene_README.txt
size: 725
-------------分割线-----------------
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

‍

# 总结

至此,对Lucene的学习基本告一段落了,由于Lucene基本都是比较基础的API,后续我们学习Elasticsearch,该框架封装好了很多Lucene的API,大大简化了全文搜索技术的使用。

已将源码上传到Gitee (opens new window)或GitHub (opens new window)上。并且创建了分支demo5,读者可以通过切换分支来查看本文的示例代码

‍

‍

在GitHub上编辑此页 (opens new window)
上次更新: 2023/5/16 10:03:58
索引库的维护
Lucene

← 索引库的维护 Lucene→

Theme by Vdoing | Copyright © 2022-2023 粤ICP备2022067627号-1 粤公网安备 44011302003646号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式