从 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

    • Elasticsearch

      • Elasticsearch 简介
      • ES 的安装和启动
      • ES 相关术语
      • ES 索引库的维护
      • ES 索引库的查询
      • ES 集成 IK 分词器
      • ES 集群
      • 使用 Java 操作 ES
      • 使用 Java 查询 ES
      • SpringDataElasticSearch
        • Spring Data ElasticSearch 简介
        • 环境准备
        • 新增 Spring 配置文件
        • 管理索引
        • 添加、更新文档
        • 删除文档
        • 查询索引库
        • 自定义查询方法
        • 分页
        • 使用原生的查询条件查询
        • 源码
    • MQ

    • MyCat

    • Lombok

  • SpringMVC

  • SpringBoot

  • Java
  • 主流框架
  • Elasticsearch
2023-05-22
目录

SpringDataElasticSearch

# 80.SpringDataElasticSearch

使用 ES 原生的 API 还是有些麻烦的,之前我们介绍过 Spring 整合了很多框架,当然也包括 ES。

# Spring Data ElasticSearch 简介

# JPA

JPA 是 Java Persistence API 的简称,中文名 Java 持久层 API,是 Java 的一个 ORM 规范。它用于在 Java 对象和关系数据库之间保存数据。 JPA 充当面向对象的领域模型和关系数据库系统之间的桥梁。

Hibernate 是实现了 JPA 规范的一种 ORM 框架。 ‍

Sun 引入新的 JPA ORM 规范出于两个原因:

  • 简化现有 Java EE 和 Java SE 应用开发工作
  • Sun 希望整合 ORM 技术,实现天下归一。 ‍

# 什么是 Spring Data

Spring Data 是一个用于简化数据库访问,并支持云服务的开源框架。其主要目标是使得对数据的访问变得方便快捷,并支持 map-reduce 框架和云计算数据服务。 Spring Data 可以极大的简化 JPA 的写法,可以在几乎不用写实现的情况下,实现对数据的访问和操作。除了 CRUD 外,还包括如分页、排序等一些常用的功能。

Spring Data 的官网:Spring Data (opens new window)

Spring Data 常用的功能模块如下:

  • Spring Data JDBC (opens new window) - Spring Data repository support for JDBC.
  • Spring Data JPA (opens new window) - Spring Data repository support for JPA.
  • Spring Data MongoDB (opens new window) - Spring based, object-document support and repositories for MongoDB.
  • Spring Data Redis (opens new window) - Easy configuration and access to Redis from Spring applications.
  • Spring Data REST (opens new window) - Exports Spring Data repositories as hypermedia-driven RESTful resources.
  • ...............

使用 Spring Data,可以简化对数据层的访问(例如 JDBC,Mybatis 和 Hibernate,Redis 等数据库)

# 什么是 Spring Data ElasticSearch

Spring Data ElasticSearch 基于 Spring data API 简化 ES 操作,将原始操作 ES 的客户端 API 进行封装 。

Spring Data 为 Elasticsearch 项目提供集成搜索引擎,可以和 Elastichsearch 交互文档和轻松地编写一个存储库数据访问层。

官网:Spring Data Elasticsearch (opens new window)

# 环境准备

相关依赖:

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-test</artifactId>
  <version>5.3.13</version>
</dependency>

<dependency>
  <groupId>org.springframework.data</groupId>
  <artifactId>spring-data-elasticsearch</artifactId>
  <version>3.0.5.RELEASE</version>
  <exclusions>
    <exclusion>
      <groupId>org.elasticsearch.plugin</groupId>
      <artifactId>transport-netty4-client</artifactId>
    </exclusion>
  </exclusions>
</dependency>

<dependency>
  <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-databind</artifactId>
  <version>2.9.0</version>
</dependency>

<dependency>
  <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-core</artifactId>
  <version>2.9.0</version>
</dependency>

<dependency>
  <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-annotations</artifactId>
  <version>2.9.0</version>
</dependency>
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
28
29
30
31
32
33
34
35

‍

# 新增 Spring 配置文件

在 resources 下新建 applicationContext.xml 文件:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:elasticsearch="http://www.springframework.org/schema/data/elasticsearch"
       xsi:schemaLocation="
	http://www.springframework.org/schema/beans
	http://www.springframework.org/schema/beans/spring-beans.xsd
	http://www.springframework.org/schema/context
	http://www.springframework.org/schema/context/spring-context.xsd
	http://www.springframework.org/schema/data/elasticsearch
	http://www.springframework.org/schema/data/elasticsearch/spring-elasticsearch-1.0.xsd">


</beans>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

‍ 配置 elasticsearch: transport-client,用来连接 ES

<elasticsearch:transport-client id="esClient"
            cluster-nodes="localhost:9301, localhost:9302, localhost:9303"
            cluster-name="my-elasticsearch"/>
1
2
3

elasticsearch: repositories:包扫描器,扫描 dao

<elasticsearch:repositories base-package="com.peterjxl.es.repositories"/>
1

类似之前 Mybatis 的时候,只需定义实体类的接口所在地方,就能扫描并创建对象

配置 elasticsearchTemplate 对象,该对象是一个模板对象,可以简化我们的操作

<!-- 配置模板对象 -->
<bean id="elasticsearchTemplate" class="org.springframework.data.elasticsearch.core.ElasticsearchTemplate">
    <constructor-arg name="client" ref="esClient"/>
</bean>
1
2
3
4

# 管理索引

  1. 创建一个 Entity 类,其实就是一个 JavaBean(pojo)映射到一个 document,需要添加一些注解进行标注
  2. 创建一个 Dao,是一个接口,需要继承 ElasticSearchRepository 接口。
  3. 编写测试代码,使用 ElasticsearchTemplate 对象的 createIndex 方法创建索引,并配置映射关系。 ‍ 新建实体类,注:自行生成 getter、setter 和 toString 方法
package com.peterjxl.es.entity;


import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;

@Document(indexName = "spring-data-es-blog", type = "article")
public class Article {


    @Id
    @Field(type = FieldType.Long, store = true)
    private long id;

    // 默认会索引
    @Field(type = FieldType.text, store = true, analyzer = "ik_smart")
    private String title;

    @Field(type = FieldType.text, store = true, analyzer = "ik_smart")
    private String content;
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

新建接口:

package com.peterjxl.es.repositories;

import com.peterjxl.es.Article;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;

public interface ArticleRepository extends ElasticsearchRepository<Article, Long> {
}
1
2
3
4
5
6
7

我们先试着创建索引:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class SpringDataESTest {

    @Autowired
    private ArticleRepository articleRepository;

    @Autowired
    private ElasticsearchTemplate template;

    @Test
    public void createIndex() throws Exception{
        // 创建索引,并配置映射关系
        template.createIndex(Article.class);
    }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

‍ 测试结果:可以看到能成功创建索引,并且带有 mappings 信息

# 添加、更新文档

先来看看 ArticleRepository 的继承关系:

在 CrudRepository 中,有很多操作索引的方法,增删改查等:

public interface CrudRepository<T, ID> extends Repository<T, ID> {
    <S extends T> S save(S var1);

    <S extends T> Iterable<S> saveAll(Iterable<S> var1);

    Optional<T> findById(ID var1);

    boolean existsById(ID var1);

    Iterable<T> findAll();

    Iterable<T> findAllById(Iterable<ID> var1);

    long count();

    void deleteById(ID var1);

    void delete(T var1);

    void deleteAll(Iterable<? extends T> var1);

    void deleteAll();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

‍ 为此,我们的 ArticleRepository 能直接用来维护文档,步骤:

  1. 创建一个 Article 对象
  2. 使用 ArticleRepository 对象向索引库中添加文档。 ‍
@Test
public void addDocument() throws Exception{
    Article article = new Article();
    article.setId(1);
    article.setTitle("Spring Data Elasticsearch");
    article.setContent("基于Spring Data Elasticsearch的项目");
    articleRepository.save(article);
}
1
2
3
4
5
6
7
8

运行结果:能看到数据

至于更新文档:ES 底层也是 Lucene,要更新文档也是删除后新增;在 ES 中,直接使用添加文档的方法即可完成更新(ID 要一样)

# 删除文档

直接使用 ArticleRepository 对象的 deleteById 方法直接删除即可:

@Test
public void deleteDocument() {
    articleRepository.deleteById(1L);
}
1
2
3
4

‍ 运行结果:数据没有了

全部删除:articleRepository.deleteAll();

# 查询索引库

直接使用 ArticleRepository 对象的查询方法即可。 ‍

# 添加数据

我们先添加一些数据(还是使用之前用过的数据)

Article article = new Article();
article.setId(2);
article.setTitle("关于买房");
article.setContent("虚假的挥霍:花几千块钱去看看海。真正的挥霍:花100万交个首付买一个名义面积70平,实际面积55平,再还30年贷款的小户型住房");
articleRepository.save(article);


article.setId(4);
article.setTitle("关于梦想");
article.setContent("编程对我而言,就像是一颗小小的,微弱的希望的种子,我甚至都不愿意让人看见它。生怕有人看见了便要嘲讽它,它太脆弱了,经不起别人的质疑");
articleRepository.save(article);


article.setId(4);
article.setTitle("关于打工");
article.setContent("其实,我对公司是有点失望的。当初给我司定位为大厂,是高于公司简介的水平的。我是希望进来后,公司能够拼一把,快速成长起来的。大厂这个层级不是只发工资就可以的,公司需要有体系化的待遇。你们给的待遇,它的价值在哪里? 公司是否作出了壁垒形成了核心竞争力? 公司的待遇,和其他公司的差异化在哪里?为什么我来你这上班,我不能去别人那上班吗? 公司需要听从员工的意见,而不是想做什么就做什么,我需要符合劳动法的公司。");
articleRepository.save(article);


for (int i = 10; i < 20; i++) {
    article.setId(i);
    article.setTitle("测试查询" + i);
    article.setContent("测试查询的内容" + i);
    articleRepository.save(article);
}
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

‍ 此时数据是不少的:

‍

# 查询全部

@Test
public void findAll() {
    Iterable<Article> articles = articleRepository.findAll();
    for (Article article : articles) {
        System.out.println(article);
    }
}
1
2
3
4
5
6
7

此时能看到控制台打印了全部数据。 ‍

# 根据 Id 查询

@Test
public void findById() {
    Article article = articleRepository.findById(3L).get();
    System.out.println(article);
}
1
2
3
4
5

# 自定义查询方法

默认方法并不多,有时候查询规则比较复杂,此时就需要自定义查询了。

我们并不用自己实现,只需根据 SpringDataES 的命名规则来命名方法,就可以实现查询了!

命名规则:

关键字 命名规则 解释 示例
and findByField1AndField2 根据 Field1 和 Field2 查询 findByTitleAndContent
or findByField1OrField2 根据 Field1 或 Field2 查询 findByTitleOrContent
is findByField 根据 Field1 查询 findByTitle
not findByFieldNot 查询不包含 Field1 的数据 findByTitleNot
between findByFieldBetween 获得指定范围的数据 findByPriceBetween
lessThanEqual findByFieldLessThan 获得小于等于指定值的数据 findByPriceLessThan

只需在接口定义方法:

public interface ArticleRepository extends ElasticsearchRepository<Article, Long> {
    List<Article> findByTitle(String title);
    List<Article> findByTitleOrContent(String title, String content);
}
1
2
3
4

‍ 在测试方法中使用:

@Test
public void testFindByTitle() {
    List<Article> articles = articleRepository.findByTitle("测试查询");
    articles.stream().forEach(System.out::println);
}

@Test
public void testFindByTitleOrContent() {
    List<Article> articles = articleRepository.findByTitleOrContent("测试查询", "编程");
    articles.stream().forEach(System.out::println);
}
1
2
3
4
5
6
7
8
9
10
11

‍ 我们运行测试方法,可以看到能正常查询出结果。 ‍

# 分页

注意,如果不设置分页信息,默认带分页,每页显示 10 条数据。

如果设置分页信息,应该在方法中添加一个参数 Pageable,我们在 dao 接口中新增一个方法:

List<Article> findByTitleOrContent(String title, String content, Pageable pageable);
1

‍ 在测试方法中使用:

@Test
public void testFindByTitleOrContentPage() {
    Pageable pageable = PageRequest.of(0, 5);
    List<Article> articles = articleRepository.findByTitleOrContent("测试查询", "编程", pageable);
    articles.stream().forEach(System.out::println);
}
1
2
3
4
5
6

‍ 可以看到只查询了 5 条记录。PageRequest.of() 方法中,第一个参数指定第几页,第二个参数指定每页的个数 ‍

# 使用原生的查询条件查询

在刚刚的自定义查询方法中,默认对搜索的内容先分词然后再进行查询,每个词之间都是 and 的关系。比如我们查询是一句话:

List<Article> articles = articleRepository.findByTitle("测试查询天气之子");
1

那么就会对“测试查询天气之子”进行分词,然后查找 title 中包含所有这些单词的 title,和我们之前使用 queryString 的效果不一样,我们想要的是每个词之间是 or 的关系。 ‍ 此时我们可以用 NativeSearchQuery 对象。使用方法:

  1. 创建一个 NativeSearchQuery 对象,设置查询条件(QueryBuilder 对象)
  2. 使用 ElasticSearchTemplate 对象执行查询
  3. 取查询结果
@Test
public void testNativeSearchQuery() {
    // 创建一个查询对象
    NativeSearchQuery query = new NativeSearchQueryBuilder()
            // 添加基本的分词条件
            .withQuery(QueryBuilders.matchQuery("title", "测试查询天气之子"))
            .build();
    // 执行查询
    List<Article> articles = template.queryForList(query, Article.class);
    articles.stream().forEach(System.out::println);
}
1
2
3
4
5
6
7
8
9
10
11

‍

# 源码

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

上次更新: 2025/5/17 12:26:09
使用 Java 查询 ES
RabbitMQ-尚硅谷

← 使用 Java 查询 ES RabbitMQ-尚硅谷→

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