Spring Data Elasticsearch 中 ElasticsearchOperations 构建查询条件的详解

Spring Data Elasticsearch 中 ElasticsearchOperations 构建查询条件的详解

  • 前言
  • 一、引入依赖
  • [二、配置 Elasticsearch](#二、配置 Elasticsearch)
  • 三、创建模型类(Entity)
  • [四、使用 `ElasticsearchOperations` 进行 CRUD 操作](#四、使用 ElasticsearchOperations 进行 CRUD 操作)
    • [1. 保存数据(Create)](#1. 保存数据(Create))
    • [2. 获取数据(Read)](#2. 获取数据(Read))
    • [3. 更新数据(Update)](#3. 更新数据(Update))
    • [4. 删除数据(Delete)](#4. 删除数据(Delete))
  • [五、构建查询条件:使用 `Criteria` 和 `CriteriaQuery`](#五、构建查询条件:使用 CriteriaCriteriaQuery)
  • [六、注解配置 Elasticsearch 索引和字段映射](#六、注解配置 Elasticsearch 索引和字段映射)
    • [1. `@Document` 注解](#1. @Document 注解)
    • [2. `@Id` 注解](#2. @Id 注解)
    • [3. `@Field` 注解](#3. @Field 注解)
    • [4. `@Setting` 注解](#4. @Setting 注解)
  • 总结

前言

在现代开发中,搜索引擎技术被广泛应用于处理大量数据和实现高效的查询。在这些技术中,Elasticsearch 是一个非常强大的工具,而 Spring Data Elasticsearch 提供了与之进行交互的便利工具。本篇文章将详细介绍如何使用 ElasticsearchOperations 进行常见查询构建操作,重点是通过 Criteria 和 Query 来构建查询条件,并演示如何使用它们进行增、删、改、查等常见操作。


一、引入依赖

首先,我们需要在 pom.xml 中添加相关的依赖,以便能够使用 Spring Data Elasticsearch 提供的功能。

xml 复制代码
	 <!-- Elasticsearch -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
        </dependency>

二、配置 Elasticsearch

在应用的 application.yaml 文件中,我们需要配置 Elasticsearch 的连接信息,通常是一个本地或远程的 Elasticsearch 。

yaml 复制代码
spring:
  elasticsearch:
    uris: 127.0.0.1:9200
    username: elastic
    password: xxxxxxxxxx
    ssl:
      verification-mode: none

这个配置将使得 Spring Data Elasticsearch 通过 ElasticsearchOperations 连接到你的 Elasticsearch 。

三、创建模型类(Entity)

在进行 Elasticsearch 操作时,通常需要一个与 Elasticsearch 索引相对应的模型类。我们以 Product 类为例:

java 复制代码
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;
@Data
@Document(indexName = "products", createIndex = true)  // 指定索引名称,并且会自动创建索引
public class Product {

    @Id
    private Long id;  // Elasticsearch 会自动使用此字段作为文档的唯一标识

    @Field(type = FieldType.Text, analyzer = "standard")  // 用来指定 Elasticsearch 中字段的数据类型和分词器
    private String name;

    @Field(type = FieldType.Double)  // 指定字段类型为 Double 类型
    private Double price;

}

此类将用于与 Elasticsearch 中的 products 索引进行交互。

四、使用 ElasticsearchOperations 进行 CRUD 操作

1. 保存数据(Create)

使用 ElasticsearchOperations 保存数据非常简单。你只需要创建一个 Product 对象并调用 save() 方法。

java 复制代码
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
import org.junit.jupiter.api.Test;

public class ProductServiceTest {

    @Autowired
    private ElasticsearchOperations elasticsearchOperations;

    @Test
    public void testSaveProduct() {
        Product product = new Product();
        product.setId(1L);
        product.setName("手机");
        product.setPrice(2999.0);

        Product savedProduct = elasticsearchOperations.save(product);  // 保存到 Elasticsearch
        System.out.println("Saved Product: " + savedProduct);
    }
}

这个简单的示例展示了如何通过 ElasticsearchOperations 保存一个 Product 对象。返回的 savedProduct 是保存后的对象,包含了 Elasticsearch 生成的 ID(如果没有指定的话)。

2. 获取数据(Read)

可以通过 get() 方法根据 ID 获取单个文档,或者通过 search() 方法根据查询条件获取多个文档。

获取单个文档

java 复制代码
@Test
public void testGetProductById() {
    Product product = elasticsearchOperations.get("1", Product.class);  // 通过 ID 获取文档
    System.out.println("Retrieved Product: " + product);
}

查询多个文档

可以通过 Criteria 来构建查询条件,然后使用 search() 方法来查询匹配的文档。

java 复制代码
import org.springframework.data.elasticsearch.core.query.Criteria;
import org.springframework.data.elasticsearch.core.query.CriteriaQuery;
import org.springframework.data.domain.PageRequest;

@Test
public void testSearchProductsByName() {
    // 构建查询条件
    Criteria criteria = new Criteria("name").is("手机");
    CriteriaQuery query = new CriteriaQuery(criteria);
    query.setPageable(PageRequest.of(0, 10));  // 设置分页

    // 执行查询
    SearchHits<Product> results = elasticsearchOperations.search(query, Product.class);
    results.forEach(hit -> System.out.println("Product: " + hit.getContent()));
}

展示了如何根据商品名称进行查询,并使用分页来限制返回的结果。

3. 更新数据(Update)

通常情况下,save() 方法会在 Elasticsearch 中执行插入或更新操作。如果想更新已有的文档,只需要重新保存即可。例如:

java 复制代码
@Test
public void testUpdateProduct() {
    Product product = elasticsearchOperations.get("1", Product.class);
    product.setPrice(2599.0);  // 修改价格
    elasticsearchOperations.save(product);  // 保存会自动执行更新
}

4. 删除数据(Delete)

删除数据可以通过 delete() 方法来完成,只需要传入文档的 ID。

java 复制代码
@Test
public void testDeleteProduct() {
    elasticsearchOperations.delete("1", Product.class);  // 删除指定 ID 的文档
}

五、构建查询条件:使用 CriteriaCriteriaQuery

ElasticsearchOperations 允许我们通过 Criteria 来构建查询条件。Criteria 类可以用来构建多种查询,包括等值查询、范围查询等。你可以通过组合 Criteria 对象来创建复杂的查询。

常见查询条件

  1. 等值查询

    java 复制代码
    Criteria criteria = new Criteria("name").is("手机");
  2. 范围查询

    java 复制代码
    Criteria criteria = new Criteria("price").between(1000, 5000);
  3. 大于查询

    java 复制代码
    Criteria criteria = new Criteria("price").greaterThan(1000);
  4. 小于查询

    java 复制代码
    Criteria criteria = new Criteria("price").lessThan(5000);
  5. 模糊查询

    java 复制代码
    Criteria criteria = new Criteria("name").contains("平板");
  6. 集合成员查询

    • in(...)

      在字段中查找包含在给定集合或数组内的文档。

      java 复制代码
      // 等同于 terms 查询,适用于 Keyword 或不分词字段
      Criteria c = new Criteria("status").in("ACTIVE", "PENDING");
    • notIn(...)

      排除指定集合或数组中的值。

      java 复制代码
      // 排除 status 为 ACTIVE 或 PENDING 的文档
      Criteria c = new Criteria("status").notIn("ACTIVE", "PENDING");
  7. 多条件查询

    java 复制代码
    Criteria criteria1 = new Criteria("name").is("手机");
    Criteria criteria2 = new Criteria("price").greaterThan(2000);
    CriteriaQuery query = new CriteriaQuery(criteria1.and(criteria2));  // AND 查询
  8. 分页和排序

    分页和排序对于大数据量查询非常重要。可以使用 Pageable 来进行分页设置,使用 Sort 来进行排序。

    分页查询

    java 复制代码
    query.setPageable(PageRequest.of(0, 10));  // 获取第1页,每页10条记录

    排序查询

    java 复制代码
    query.addSort(Sort.by(Sort.Order.asc("price")));  // 按价格升序排序

    复合查询

    使用 CriteriaQuery,你可以将多个查询条件通过 andor 进行组合:

    java 复制代码
    Criteria criteria1 = new Criteria("name").is("手机");
    Criteria criteria2 = new Criteria("price").greaterThan(2000);
    CriteriaQuery query = new CriteriaQuery(criteria1.and(criteria2));  // AND 查询

六、注解配置 Elasticsearch 索引和字段映射

1. @Document 注解

@Document 注解用于指定类对应的 Elasticsearch 索引。在索引的配置中,可以指定索引名称、是否自动创建索引等。

java 复制代码
@Document(indexName = "products", createIndex = true)  // 指定索引名称,并且会自动创建索引
public class Product {
    @Id
    private Long id;

    @Field(type = FieldType.Text, analyzer = "standard")  // 用来指定 Elasticsearch 中字段的数据类型和分词器
    private String name;

    @Field(type = FieldType.Double)  // 指定字段类型为 Double 类型
    private Double price;
}

2. @Id 注解

@Id 注解用于标识文档的唯一标识符字段。这个字段会被作为 Elasticsearch 索引文档的 _id

java 复制代码
@Id
private String id;

3. @Field 注解

@Field 注解用于指定字段在 Elasticsearch 中的类型、分词器等配置。它支持多种类型,如 TextKeywordDouble 等,并且可以配置分词器(analyzer)等属性。

java 复制代码
@Field(type = FieldType.Text, analyzer = "standard")
private String name;

@Field(type = FieldType.Double)
private Double price;

4. @Setting 注解

还可以使用 @Setting 注解来配置索引的详细设置,如分片数、副本数等。

java 复制代码
@Setting(shards = 3, replicas = 2)
@Document(indexName = "products")
public class Product {
    // Fields ...
}

总结

  • ElasticsearchOperations:适合常见 CRUD 和基础查询(等值、范围、模糊、组合、分页、排序)。

  • Criteria + CriteriaQuery:以链式方式构建查询,无需掌握原生 DSL 语法。

  • 注解映射 :通过 @Document@Field@Setting 精细控制索引与字段。

  • 对于聚合、高亮、异步和大批量操作等高级需求,应使用 ElasticsearchRestTemplate 或直接调用 Elasticsearch Java 客户端。

相关推荐
程序员爱钓鱼8 分钟前
Go语言实战案例-开发一个Markdown转HTML工具
前端·后端·go
2301_7816686116 分钟前
Elasticsearch 02
大数据·elasticsearch·搜索引擎
小小菜鸡ing24 分钟前
pymysql
java·服务器·数据库
getapi27 分钟前
shareId 的产生与传递链路
java
桦说编程37 分钟前
爆赞!完全认同!《软件设计的哲学》这本书深得我心
后端
thinktik1 小时前
还在手把手教AI写代码么? 让你的AWS Kiro AI IDE直接读飞书需求文档给你打工吧!
后端·serverless·aws
我没想到原来他们都是一堆坏人1 小时前
(未完待续...)如何编写一个用于构建python web项目镜像的dockerfile文件
java·前端·python
沙二原住民2 小时前
提升数据库性能的秘密武器:深入解析慢查询、连接池与Druid监控
java·数据库·oracle
mabo_9704@163.com2 小时前
SpringAI调用MCP服务的实现思路
spring·ai