springboot+elasticsearch实现分页查询,模糊查询
·
下面是一个基于 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())
更多推荐
所有评论(0)