Elasticsearch 之 ElasticsearchRestTemplate 普通查询

server/2025/3/31 11:09:38/

前言:

上一篇我们分享了 Spring Boot 整合 Elasticsearch 使用 ElasticsearchRepository 完成简单的增删改查,我们发现 ElasticsearchRepository 中很多稍微复杂一些的查询就会显示方法过期,对于 Elasticsearch 7.X 版本,我们可以使用 ElasticsearchRestTemplate 来进行相关增删改查。

Elasticsearch 系列文章传送门

Elasticsearch 基础篇【ES

Elasticsearch Windows 环境安装

QueryBuilders

QueryBuilders 是 Elasticsearch 中的一个工具类,用于构建各种复杂的查询的条件,在实际业务场景中,经常需要构建复杂的条件查询,如范围查询、布尔查询、模糊查询等场景,QueryBuilders 提供了构建这些复杂的查询能力,替代了手动编写复杂的 JSON 格式的查询 Elasticsearch 语句,在使用 ElasticsearchRestTemplate 完成 Elasticsearch 的各种复杂查询的时候,我们会使用到 QueryBuilders。

普通查询

ElasticsearchRestTemplate 是 Spring Data Elasticsearch 提供的一个操作 Elasticsearch 的模板类,它封装了在 Java 应用程序中执行各种 Elasticsearch 操作的方法,下面我们演示使用 ElasticsearchRestTemplate 来进行 Elasticsearch 的增删改查。

案例演示准备

我使用车作为业务模型进行 Elasticsearch 的 ElasticsearchRestTemplate 演示,车对象代码如下:

@Data
@Document(indexName = "car", shards = 1, replicas = 1)
public class CarDO {private Long id;private String color;private String model;private double price;}

如上代码我们定义了一个 car 的索引关于车的相关文档都存储在了 car 这个索引中了。

save(保存文档)

ElasticsearchRestTemplate 使用 save 方法来保存单个文档,代码如下:

public void saveCar(CarDO carDO) {elasticsearchRestTemplate.save(carDO);List<CarDO> list = new ArrayList<>();list.add(carDO);elasticsearchRestTemplate.save(list);
}

可以看到 save 方法也是支持批量保存的。

get(查詢文档)

ElasticsearchRestTemplate 使用 get 方法根据文档 id 来查询文档,代码如下:

public CarDO queryCarById(Long id) {return elasticsearchRestTemplate.get(String.valueOf(id), CarDO.class);
}

我们传入了文档 id 和车对象的的 Class 即可根据文档 id 查询文档对象。

update(更新文档)

ElasticsearchRestTemplate 使用 update 方法来更新文档,代码如下:

public void updateCar(CarDO carDO) {UpdateQuery.Builder builder = UpdateQuery.builder(String.valueOf(carDO.getId()));Document document = Document.create();document.put("color", carDO.getColor());document.put("model", carDO.getModel());document.put("price", carDO.getPrice());builder.withDocument(document);elasticsearchRestTemplate.update(builder.build(), IndexCoordinates.of("car"));
}

可以看到 update 方法是根据 UpdateQuery 对象和索引名称来更新的。

bulkUpdate(批量更新文档)

ElasticsearchRestTemplate 使用 updbulkUpdate 方法来更新文档,代码如下:

public void batchUpdateCar(CarDO carDO) {UpdateQuery.Builder builder = UpdateQuery.builder(String.valueOf(carDO.getId()));Document document = Document.create();document.put("color", carDO.getColor());document.put("model", carDO.getModel());document.put("price", carDO.getPrice());builder.withDocument(document);List<UpdateQuery> updateQueryList = new ArrayList<>();updateQueryList.add(builder.build());elasticsearchRestTemplate.bulkUpdate(updateQueryList, IndexCoordinates.of("car"));
}

可以看到 bulkUpdate方法只是在 update 方法的基础上传入了 UpdateQuery List 对象来实现批量更新。

detele(删除文档)

ElasticsearchRestTemplate 使用 detele 方法来删除文档,代码如下:

public void detele(Long id) {CarDO carDO = new CarDO();carDO.setId(id);elasticsearchRestTemplate.delete(carDO);
}

ElasticsearchRestTemplate 删除文档的方法非常简单,传入对象即可根据文档 id 删除文档,,。

detele(批量删除文档)

ElasticsearchRestTemplate 批量删除文档同样是使用 delete 方法,代码如下:

public void batchDetele(String model) {NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();queryBuilder.withQuery(QueryBuilders.matchQuery("model", model));elasticsearchRestTemplate.delete(queryBuilder.build(), CarDO.class);
}

可以看到批量删除使用 delete 方法的时候传入了一个 Query 对称。

PageRequest(分页查询文档)

ElasticsearchRestTemplate 分页查询依赖的是 PageRequest ,PageRequest 会构造一个分页对象来实现分页查询,代码如下:

public List<CarDO> pageList(int currentPage, int pageSize) {NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();queryBuilder.withPageable(PageRequest.of(currentPage - 1, pageSize)).build();queryBuilder.withQuery(QueryBuilders.matchQuery("color", "雅灰"));SearchHits<CarDO> search = elasticsearchRestTemplate.search(queryBuilder.build(), CarDO.class);return search.getSearchHits().stream().map(SearchHit::getContent).collect(Collectors.toList());
}

可以看到分页查询最终使用的是 search 方法。

SortBuilders(排序查询文档)

ElasticsearchRestTemplate 使用 withSort 来实现文档的查询排序,代码如下:

public List<CarDO> sortCar() {NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();queryBuilder.withSort(SortBuilders.fieldSort("price").order(SortOrder.DESC));SearchHits<CarDO> search = elasticsearchRestTemplate.search(queryBuilder.build(), CarDO.class);return search.getSearchHits().stream().map(SearchHit::getContent).collect(Collectors.toList());
}

可以看到我们在构造查询条件的时候使用 SortBuilders 来指定排序字段和排序方式,即可完成文档的排序查询。

rangeQuery(范围查询文档)

ElasticsearchRestTemplate 使用 rangeQuery 来实现按范围来查询文档来,代码如下:

public List<CarDO> priceRangeCar(double priceBegin, double priceEnd) {NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();queryBuilder.withFilter(QueryBuilders.rangeQuery("price").gt(priceBegin).lt(priceEnd));SearchHits<CarDO> search = elasticsearchRestTemplate.search(queryBuilder.build(), CarDO.class);return search.getSearchHits().stream().map(SearchHit::getContent).collect(Collectors.toList());
}

可以看到使用 QueryBuilders 构建查询条件的时候使用 rangeQuery 执行需要范围查询的字段,即可完成范围查询。

in 查询(同一个字段多条件查询)

ElasticsearchRestTemplate 使用 termsQuery 即可完成同一个字段的多条件查询,代码如下:

public List<CarDO> priceInCar(List<Double> priceList) {NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();queryBuilder.withQuery(QueryBuilders.termsQuery("price", priceList));SearchHits<CarDO> search = elasticsearchRestTemplate.search(queryBuilder.build(), CarDO.class);return search.getSearchHits().stream().map(SearchHit::getContent).collect(Collectors.toList());
}

可以看到我们在构建查询条件的时候,指定字段后传入一个 List 数组即可完成多条件查询,也就是类似 MySQL 的 in 查询。

or 查询

在真实项目的业务场景中 or 条件查询也是一种很场景的业务场景,ElasticsearchRestTemplate 使用 boolQuery 和多个 BoolQueryBuilder 拼接的方式来实现 or 条件的查询代码如下:

public List<CarDO> queryOrCar() {//(颜色:雅灰 and 价格:19.98) or (型号:su7)//or 使用 should//and 使用 must//not 使用 must_notNativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();//(颜色:雅灰 and 价格:19.98)BoolQueryBuilder orOne = QueryBuilders.boolQuery().must(QueryBuilders.termQuery("model", "xiaopeng")).must(QueryBuilders.termQuery("price", 19.98));//型号:su7BoolQueryBuilder orTwo = QueryBuilders.boolQuery().must(QueryBuilders.termQuery("model", "su7"));BoolQueryBuilder should = QueryBuilders.boolQuery().should(orOne).should(orTwo);SearchHits<CarDO> search = elasticsearchRestTemplate.search(queryBuilder.withQuery(should).build(), CarDO.class);return search.getSearchHits().stream().map(SearchHit::getContent).collect(Collectors.toList());
}

上述代码我们就完成了一个 [ (颜色:雅灰 and 价格:19.98) or (型号:su7) ] 这样一个 or 条件的查询。

ElasticsearchRestTemplate or 查询简单总结如下:

  • or 条件拼接使用 shoud。
  • and 使用 must。
  • not and 使用 must_not。

constantScoreQuery(评分查询文档)

constantScoreQuery 是 Elasticsearch 的一种查询类型,只不过这种查询类型略微有点特殊,用于在查询的时候指定一个固定的评分(默认是 1.0),而其他类型的查询如 termsQuery、matchQuery 是根据,文档的相关性来动态计算评分的,constantScoreQuery 的主要作用就是简化 Elasticsearch 的评分机制,高效的过滤文档,代码如下:

public List<CarDO> constantScoreQuery() {NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();ConstantScoreQueryBuilder constantScoreQueryBuilder = QueryBuilders.constantScoreQuery(QueryBuilders.termQuery("model", "xiaopeng").boost(1.1f));SearchHits<CarDO> search = elasticsearchRestTemplate.search(queryBuilder.withQuery(constantScoreQueryBuilder).build(), CarDO.class);return search.getSearchHits().stream().map(SearchHit::getContent).collect(Collectors.toList());
}

总结:本篇我们使用了 ElasticsearchRestTemplate 实现了 Elasticsearch 的增删改查、分页、排序、范围、in or 等查询方法,ElasticsearchRestTemplate 操作简单且支持丰富的查询方法,是我们在 Spring 项目中操作 Elasticsearch 的好帮手,希望本篇的分享可以帮助到不是特熟悉 ElasticsearchRestTemplate 操作的朋友们,下一篇我将继续分享使用 ElasticsearchRestTemplate 进行更为复杂的聚合查询。

如有不正确的地方欢迎各位指出纠正。


http://www.ppmy.cn/server/179787.html

相关文章

React企业级复杂搜索方案深度实战

一、高阶搜索架构设计 1.1 分层架构模式 // 核心分层结构 src/ ├─ features/ │ ├─ search/ │ │ ├─ api/ // API通信层 │ │ ├─ domain/ // 领域模型 │ │ ├─ hooks/ // 业务逻辑Hook │ │ ├─ components/ //…

RT-Thread CI编译产物artifacts自动上传功能介绍

近期在RT-Thread开源项目中&#xff0c;我们引入了一项实用的功能改进——将每次CI&#xff08;持续集成&#xff09;编译生成的产物&#xff08;artifacts&#xff09;自动上传到GitHub&#xff0c;方便开发者和用户能够更便捷地获取和测试最新的编译结果。 参考链接&#xf…

春日焕新居:约克VRF中央空调,科技赋能,带你开启健康呼吸新时代

春回大地,万物复苏的季节里,无数家庭怀揣美好憧憬之心开启家居焕新装修。然而,当精心挑选的建材逐渐构筑起理想家的雏形,往往伴随着甲醛等有害气体的困扰,如同一道无形的屏障,阻挡我们对健康家居生活的追求。别担心,约克VRF中央空调凭借其卓越的产品性能和服务,为您打造一个健康…

HTTP 1.0和2.0 有什么区别?

HTTP 1.0和HTTP 2.0是互联网中用于数据传输的重要协议&#xff0c;两者在功能和性能上有显著差异。 以下是它们的主要区别&#xff1a; HTTP 1.0 的特点&#xff1a; 单一连接&#xff1a;每个请求需要独立连接&#xff0c;导致高延迟和资源浪费。文本传输&#xff1a;使用文…

【更新中】【React】基础版React + Redux实现教程,自定义redux库和react-redux库

本项目是一个在react中&#xff0c;使用 redux 管理状态的基础版实现教程&#xff0c;用简单的案例练习redux的使用&#xff0c;旨在帮助学习 redux 的状态管理机制&#xff0c;包括 store、action、reducer、dispatch 等核心概念。 项目地址&#xff1a;https://github.com/Yv…

批量给 PDF 页面添加超链接

让我们的 PDF 文档上传到互联网的时候&#xff0c;我们可能需要对其做一些处理&#xff0c;比如说我们希望别人在点击 PDF 文档页面的时候就跳转到指定的链接&#xff0c;那我们就需要给 PDF 文档的页面上添加链接。今天就给大家介绍一下如何同时对多个 PDF 文档的所有页面添加…

SpringMVC请求与响应深度解析:从核心原理到高级实践

一、SpringMVC架构与核心组件剖析 SpringMVC是基于Java的MVC设计模型实现的轻量级Web框架&#xff0c;其核心架构围绕前端控制器模式构建。以下是核心组件及其作用&#xff1a; DispatcherServlet 作为前端控制器&#xff0c;所有请求首先到达此处。它负责请求分发、协调组件协…

ORA-00600 [2662]

一、数据库启动报ORA-00600[2662] [oraclenode1 ora11g]$ sqlplus / as sysdbaSQL*Plus: Release 11.2.0.3.0 Production on Thu Dec 22 14:37:00 2011Copyright (c) 1982, 2011, Oracle. All rights reserved.Connected to an idle instance.SQL> startup ORACLE instanc…