Elasticsearch7通过Low Level Rest Client处理字段变更及重索引问题咨询
Elasticsearch 7.0.x 低级别Rest Client问题解决方案
1. 实现仅ACTIVE状态文档可检索的重索引操作
你当前的问题本质是检索逻辑没有过滤status字段,若要彻底清理索引中的inactive文档,可通过以下步骤用Low Level Rest Client调用重索引接口实现:
核心代码实现
import org.apache.http.HttpHost; import org.elasticsearch.client.Request; import org.elasticsearch.client.Response; import org.elasticsearch.client.RestClient; import org.apache.http.util.EntityUtils; // 初始化Low Level Rest Client实例,全局复用即可 RestClient restClient = RestClient.builder( new HttpHost("你的ES地址", 9200, "http") ).build(); // 构造重索引请求,仅迁移status为ACTIVE的文档到新索引 Request reindexReq = new Request("POST", "/_reindex"); String reindexBody = """ { "source": { "index": "你的原索引名", "query": { "term": { "status": "ACTIVE" } } }, "dest": { "index": "你的新索引名" } } """; reindexReq.setJsonEntity(reindexBody); // 执行重索引 Response reindexResp = restClient.performRequest(reindexReq); if (reindexResp.getStatusLine().getStatusCode() == 200) { // 重索引成功后切换业务别名到新索引,业务侧无需修改检索地址 Request aliasReq = new Request("POST", "/_aliases"); String aliasBody = """ { "actions": [ {"remove": {"index": "你的原索引名", "alias": "你的业务检索别名"}}, {"add": {"index": "你的新索引名", "alias": "你的业务检索别名"}} ] } """; aliasReq.setJsonEntity(aliasBody); restClient.performRequest(aliasReq); }
轻量替代方案(无需重索引)
如果不需要清理存量inactive文档,直接在现有检索接口新增status过滤条件即可:
@RestController public class SearchController { @Autowired private RestClient restClient; private String indexName = "你的业务索引名"; @GetMapping("/retrieve") public String retrieve (String id) throws IOException { Request request = new Request("GET", indexName +"/_search"); // 新增ACTIVE状态过滤 String searchBody = """ { "query": { "bool": { "must": [ {"term": {"id": "%s"}}, {"term": {"status": "ACTIVE"}} ] } } } """.formatted(id); request.setJsonEntity(searchBody); Response response = restClient.performRequest(request); return EntityUtils.toString(response.getEntity()); } }
2. 数据库字段变更时的ES数据同步实现
首先需要监听数据库的变更事件,可通过业务代码侵入(更新数据库后主动触发同步)或中间件监听(Canal/Debezium订阅binlog)的方式获取变更的文档ID和最新字段值,再调用Low Level Rest Client完成ES数据更新与查询:
核心代码实现
// 监听到数据库status字段变更后触发的同步逻辑 public void syncDbChangeToEs(String docId, String newStatus) throws IOException { // 1. 更新ES对应文档的status字段 Request updateReq = new Request("POST", indexName + "/_update/" + docId); String updateBody = """ { "doc": { "status": "%s" } } """.formatted(newStatus); updateReq.setJsonEntity(updateBody); restClient.performRequest(updateReq); // 2. 获取ES中变更后的最新文档数据 Request getReq = new Request("GET", indexName + "/_doc/" + docId); Response getResp = restClient.performRequest(getReq); String latestDocData = EntityUtils.toString(getResp.getEntity()); // 后续自行处理最新数据逻辑 }
注意事项
- 低级别Rest Client的依赖版本需要和ES服务端版本保持一致,避免兼容性问题,Maven依赖如下:
<dependency> <groupId>org.elasticsearch.client</groupId> <artifactId>elasticsearch-rest-client</artifactId> <version>7.0.1</version> </dependency>
- 数据量较大的重索引操作可添加
wait_for_completion=false参数异步执行,避免请求超时 - 可给业务检索别名添加默认过滤条件,所有走别名的查询自动过滤inactive文档,无需每次查询都写status过滤逻辑
内容的提问来源于stack exchange,提问作者srinias
相关产品推荐
相关产品推荐

