You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于SpringBoot的Elasticsearch RestHighLevelClient扩展搜索功能

实现书籍搜索功能的具体方案

嘿,你已经把基础的增查(按ID)功能跑通了,接下来实现搜索功能其实很简单,我结合ES 6.1的RestHighLevelClient特性给你一步步拆解:

第一步:新增搜索接口(Controller层)

先在你的书籍Controller里加一个支持关键词、分页参数的搜索接口:

@RestController
@RequestMapping("/books")
public class BookController {

    @Autowired
    private BookService bookService;

    // 你的插入、按ID查询接口...

    @GetMapping("/search")
    public ResponseEntity<Map<String, Object>> searchBooks(
            @RequestParam String keyword,
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "10") int size) throws IOException {
        Map<String, Object> result = bookService.searchBooks(keyword, page, size);
        return ResponseEntity.ok(result);
    }
}

第二步:实现搜索核心逻辑(Service层)

这部分是实现搜索的核心,我们用RestHighLevelClient构建多字段模糊搜索请求,还可以加上分页、高亮效果(可选):

@Service
public class BookService {

    @Autowired
    private RestHighLevelClient restHighLevelClient;

    // 替换成你实际的ES索引名称
    private static final String INDEX_NAME = "books";

    public Map<String, Object> searchBooks(String keyword, int page, int size) throws IOException {
        // 1. 初始化搜索请求和源构建器
        SearchRequest searchRequest = new SearchRequest(INDEX_NAME);
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();

        // 2. 构建多字段匹配查询(同时搜索书名、作者、简介)
        // 开启*模糊匹配*,容错少量拼写错误
        MultiMatchQueryBuilder matchQuery = QueryBuilders.multiMatchQuery(keyword, "title", "author", "description")
                .fuzziness(Fuzziness.AUTO);

        sourceBuilder.query(matchQuery);
        // 3. 设置分页(注意:ES的page是从0开始计数的)
        sourceBuilder.from(page);
        sourceBuilder.size(size);
        // 可选:添加高亮效果,让搜索关键词在结果中突出显示
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.field("title")
                .preTags("<em>")
                .postTags("</em>");
        sourceBuilder.highlighter(highlightBuilder);

        searchRequest.source(sourceBuilder);

        // 4. 执行搜索请求
        SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);

        // 5. 处理搜索结果,转换成业务需要的格式
        Map<String, Object> result = new HashMap<>();
        result.put("total", searchResponse.getHits().getTotalHits());
        List<Book> books = new ArrayList<>();
        for (SearchHit hit : searchResponse.getHits().getHits()) {
            // 把ES返回的JSON文档转换成Book实体
            Book book = new ObjectMapper().readValue(hit.getSourceAsString(), Book.class);
            // 替换高亮字段(如果存在)
            Map<String, HighlightField> highlightFields = hit.getHighlightFields();
            if (highlightFields.containsKey("title")) {
                book.setTitle(highlightFields.get("title").getFragments()[0].toString());
            }
            books.add(book);
        }
        result.put("books", books);
        return result;
    }

    // 你的插入、按ID查询方法...
}

补充:Book实体类示例

确保你的实体类字段和ES文档的字段对应(可以用@JsonProperty指定映射关系):

public class Book {
    private String id;
    private String title;
    private String author;
    private String description;
    // 省略getter、setter、构造方法
}

第三步:测试搜索接口

用Postman或者浏览器直接调用即可,比如:
GET 127.0.0.1:8080/books/search?keyword=Spring&page=0&size=5
你会得到包含总匹配条数、书籍列表的JSON响应,开启高亮后,书名里的关键词会被<em>标签包裹。

额外实用提示

  • 如果需要精确匹配(比如按书籍分类搜索),可以用TermQueryBuilder代替多匹配查询
  • 确保RestHighLevelClient的依赖版本和ES服务器版本完全一致(ES 6.1对应client的6.1.x版本),避免兼容性问题
  • 复杂组合查询(比如关键词+价格范围)可以用BoolQueryBuilder把多个查询条件组合起来

内容的提问来源于stack exchange,提问作者AchillesVan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 07:29:10