下面是一个基于 Spring Boot + Elasticsearch 的完整示例,展示如何实现 分页查询模糊查询(支持多字段匹配)
(假设使用的是 Spring Boot 3.x + Elasticsearch 8.x 客户端


🧩 一、引入依赖

<!-- pom.xml -->
<dependencies>
    <!-- Spring Boot Elasticsearch -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
    </dependency>

    <!-- lombok 可选 -->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
</dependencies>

🏗️ 二、配置文件(application.yml)

spring:
  elasticsearch:
    uris: http://localhost:9200
    username: elastic
    password: elastic@123

⚠️ 注意:如果是 ES 8.x,需要使用 HTTP Basic 认证或关闭安全验证。


📦 三、实体类定义

package com.example.esdemo.entity;

import lombok.Data;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;

@Data
@Document(indexName = "user_index") // 索引名
public class User {
    @Id
    private String id;
    private String name;
    private String address;
    private Integer age;
}

📚 四、Repository接口定义

package com.example.esdemo.repository;

import com.example.esdemo.entity.User;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;

public interface UserRepository extends ElasticsearchRepository<User, String> {
}

⚙️ 五、Service层实现模糊分页查询

Spring Data Elasticsearch 默认提供 NativeQueryBuilder(Spring Boot 3.x 对应 ES 8 的 client)。

package com.example.esdemo.service;

import co.elastic.clients.elasticsearch._types.query_dsl.QueryBuilders;
import co.elastic.clients.elasticsearch._types.query_dsl.BoolQuery;
import co.elastic.clients.elasticsearch._types.query_dsl.MatchQuery;
import co.elastic.clients.elasticsearch._types.query_dsl.WildcardQuery;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.client.elc.NativeQuery;
import org.springframework.data.elasticsearch.client.elc.NativeQueryBuilder;
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.stereotype.Service;
import com.example.esdemo.entity.User;

@Service
@RequiredArgsConstructor
public class UserService {

    private final ElasticsearchOperations operations;

    /**
     * 模糊分页查询
     * @param keyword 搜索关键字
     * @param page 页码(从0开始)
     * @param size 每页大小
     */
    public SearchHits<User> search(String keyword, int page, int size) {
        // 构造模糊匹配条件(name 或 address 模糊匹配)
        BoolQuery boolQuery = QueryBuilders.bool()
                .should(WildcardQuery.of(q -> q.field("name").value("*" + keyword + "*"))._toQuery())
                .should(WildcardQuery.of(q -> q.field("address").value("*" + keyword + "*"))._toQuery())
                .build();

        NativeQuery query = new NativeQueryBuilder()
                .withQuery(boolQuery._toQuery())
                .withPageable(PageRequest.of(page, size))
                .build();

        return operations.search(query, User.class);
    }
}

🚀 六、Controller层测试接口

package com.example.esdemo.controller;

import com.example.esdemo.entity.User;
import com.example.esdemo.service.UserService;
import lombok.RequiredArgsConstructor;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/user")
@RequiredArgsConstructor
public class UserController {

    private final UserService userService;

    @GetMapping("/search")
    public SearchHits<User> search(
            @RequestParam String keyword,
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "10") int size
    ) {
        return userService.search(keyword, page, size);
    }
}

📘 七、示例请求

示例请求:

GET http://localhost:8080/user/search?keyword=张&page=0&size=5

示例返回(部分):

{
  "searchHits": [
    {
      "id": "1",
      "content": {
        "name": "张三",
        "address": "北京海淀区",
        "age": 28
      },
      "score": 1.2
    },
    {
      "id": "2",
      "content": {
        "name": "李张",
        "address": "上海浦东新区",
        "age": 32
      },
      "score": 0.9
    }
  ],
  "totalHits": 2
}

🔍 八、关键说明

功能 说明
分页 通过 PageRequest.of(page, size) 实现
模糊匹配 WildcardQuery (*keyword*) 支持任意位置模糊
多字段查询 使用 bool.should() 组合多个字段匹配
返回结果 SearchHits<User> 包含内容、分数、总条数

✅ 可扩展建议

  • 若需 高性能全文搜索 → 改用 matchQuery + analyzer
  • 若需 多条件组合查询(年龄范围 + 模糊匹配) → 使用 bool.must() / must_not()
  • 若需 排序 → 在 NativeQueryBuilder.withSorts(Sort.by("age").descending())
Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐