从 01 开始 从 01 开始
首页
  • 📚 计算机基础

    • 计算机简史
    • 数字电路
    • 计算机组成原理
    • 操作系统
    • Linux
    • 计算机网络
    • 数据库
    • 编程工具
    • 装机
  • 🎨 前端

    • Node
  • JavaSE
  • Java 高级
  • JavaEE

    • 构建、依赖管理
    • Ant
    • Maven
    • 日志框架
    • Junit
    • JDBC
    • XML-JSON
  • JavaWeb

    • 服务器软件
    • 环境管理和配置管理-科普篇
    • Servlet
  • Spring

    • Spring基础
  • 主流框架

    • Redis
    • Mybatis
    • Lucene
    • Elasticsearch
    • RabbitMQ
    • MyCat
    • Lombok
  • SpringMVC

    • SpringMVC 基础
  • SpringBoot

    • SpringBoot 基础
  • Windows 使用技巧
  • 手机相关技巧
  • 最全面的输入法教程
  • 最全面的浏览器教程
  • Office
  • 图片类工具
  • 效率类工具
  • 最全面的 RSS 教程
  • 码字工具
  • 各大平台
  • 校招
  • 五险一金
  • 职场规划
  • 关于离职
  • 杂谈
  • 自媒体
  • 📖 读书

    • 读书工具
    • 走进科学
  • 🌍 英语

    • 从零开始学英语
    • 英语兔的相关视频
    • Larry 想做技术大佬的相关视频
  • 🏛️ 政治

    • 反腐
    • GFW
    • 404 内容
    • 审查与自我审查
    • 互联网
    • 战争
    • 读书笔记
  • 💰 经济

    • 关于税
    • 理财
  • 💪 健身

    • 睡眠
    • 皮肤
    • 口腔健康
    • 学会呼吸
    • 健身日志
  • 🏠 其他

    • 驾驶技能
    • 租房与买房
    • 厨艺
  • 电影

    • 电影推荐
  • 电视剧
  • 漫画

    • 漫画软件
    • 漫画推荐
  • 游戏

    • Steam
    • 三国杀
    • 求生之路
  • 小说
  • 关于本站
  • 关于博主
  • 打赏
  • 网站动态
  • 友人帐
  • 从零开始搭建博客
  • 搭建邮件服务器
  • 本站分享
  • 🌈 生活

    • 2022
    • 2023
    • 2024
    • 2025
  • 📇 文章索引

    • 文章分类
    • 文章归档

晓林

程序猿,自由职业者,博主,英语爱好者,健身达人
首页
  • 📚 计算机基础

    • 计算机简史
    • 数字电路
    • 计算机组成原理
    • 操作系统
    • Linux
    • 计算机网络
    • 数据库
    • 编程工具
    • 装机
  • 🎨 前端

    • Node
  • JavaSE
  • Java 高级
  • JavaEE

    • 构建、依赖管理
    • Ant
    • Maven
    • 日志框架
    • Junit
    • JDBC
    • XML-JSON
  • JavaWeb

    • 服务器软件
    • 环境管理和配置管理-科普篇
    • Servlet
  • Spring

    • Spring基础
  • 主流框架

    • Redis
    • Mybatis
    • Lucene
    • Elasticsearch
    • RabbitMQ
    • MyCat
    • Lombok
  • SpringMVC

    • SpringMVC 基础
  • SpringBoot

    • SpringBoot 基础
  • Windows 使用技巧
  • 手机相关技巧
  • 最全面的输入法教程
  • 最全面的浏览器教程
  • Office
  • 图片类工具
  • 效率类工具
  • 最全面的 RSS 教程
  • 码字工具
  • 各大平台
  • 校招
  • 五险一金
  • 职场规划
  • 关于离职
  • 杂谈
  • 自媒体
  • 📖 读书

    • 读书工具
    • 走进科学
  • 🌍 英语

    • 从零开始学英语
    • 英语兔的相关视频
    • Larry 想做技术大佬的相关视频
  • 🏛️ 政治

    • 反腐
    • GFW
    • 404 内容
    • 审查与自我审查
    • 互联网
    • 战争
    • 读书笔记
  • 💰 经济

    • 关于税
    • 理财
  • 💪 健身

    • 睡眠
    • 皮肤
    • 口腔健康
    • 学会呼吸
    • 健身日志
  • 🏠 其他

    • 驾驶技能
    • 租房与买房
    • 厨艺
  • 电影

    • 电影推荐
  • 电视剧
  • 漫画

    • 漫画软件
    • 漫画推荐
  • 游戏

    • Steam
    • 三国杀
    • 求生之路
  • 小说
  • 关于本站
  • 关于博主
  • 打赏
  • 网站动态
  • 友人帐
  • 从零开始搭建博客
  • 搭建邮件服务器
  • 本站分享
  • 🌈 生活

    • 2022
    • 2023
    • 2024
    • 2025
  • 📇 文章索引

    • 文章分类
    • 文章归档
  • JavaSE

  • JavaSenior

  • JavaEE

  • JavaWeb

  • Spring

  • 主流框架

    • Redis

    • Mybatis

    • Lucene

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

    • MQ

    • MyCat

    • Lombok

  • SpringMVC

  • SpringBoot

  • 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,读者可以通过切换分支来查看本文的示例代码

上次更新: 2025/6/3 09:31:54
索引库的维护
Elasticsearch 简介

← 索引库的维护 Elasticsearch 简介→

最近更新
01
学点统计学:轻松识破一本正经的胡说八道
06-05
02
2025 年 5 月记
05-31
03
《贫穷的本质》很棒,但可能不适合你
05-27
更多文章>
Theme by Vdoing | Copyright © 2022-2025 | 粤 ICP 备 2022067627 号 -1 | 粤公网安备 44011302003646 号 | 点击查看十年之约
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式