为什么要整理ES UpdateByQuery的API?因为我当时写的时候有点费劲,官网给了Nested结构的Java Api一些例子,但是我觉得就是草草了事,官网更加侧重于DSL语句的语法。我理解的Api就是拿来即用,不要浪费太多时间。
我们就拿学生和爱好也举例子,爱好为嵌套结构,一个学生的爱好可以有多个。
把出生日期是1999年9月9日的童鞋,备注更新为重阳节活动候选人(根据条件更新某个字段):
public void testUpdateField() {
UpdateByQueryRequest updateByQueryRequest = new UpdateByQueryRequest("student");
Map<String, Object> paramsMap = new HashMap<String, Object>();
paramsMap.put("mark", "重阳节活动候选人");
ScriptType type = ScriptType.INLINE;
String lang = "painless";
updateByQueryRequest.setScript(new Script(type, lang, "ctx._source.mark= params.mark", paramsMap));
updateByQueryRequest.setQuery(new TermQueryBuilder("birthday.keyword", "1999-9-9"));
updateByQueryRequest.setBatchSize(100);
updateByQueryRequest.setAbortOnVersionConflict(false);
this.getResponseBySearchRequest(updateByQueryRequest);
}
把所有的男童鞋,爱好增加一个看美女(根据条件把嵌套类型hobbyList增加一个爱好):
public void testNestedAdd() {
UpdateByQueryRequest updateByQueryRequest = new UpdateByQueryRequest("student");
HobbyDto hobbyDto = new HobbyDto();
hobbyDto.setId(102);
hobbyDto.setName("看美女");
Map<String, Object> params = BaseUtil.java2Map(hobbyDto);
Map<String, Object> parameters = Collections.singletonMap("jsonMap", params);
ScriptType type = ScriptType.INLINE;
String lang = "painless";
updateByQueryRequest.setScript(new Script(type, lang, "ctx._source.hobbyList.add(params.jsonMap)", parameters));
updateByQueryRequest.setQuery(new TermQueryBuilder("sex.keyword", "男"));
updateByQueryRequest.setBatchSize(100);
updateByQueryRequest.setAbortOnVersionConflict(false);
this.getResponseBySearchRequest(updateByQueryRequest);
}
把名字叫曹尼玛的童鞋,爱好是102(看美女)的同学删除掉:
public void testNestedDelete() {
UpdateByQueryRequest updateByQueryRequest = new UpdateByQueryRequest("student");
Map<String, Object> paramsMap = new HashMap<String, Object>(16);
paramsMap.put("id", 102);
ScriptType type = ScriptType.INLINE;
String lang = "painless";
updateByQueryRequest.setScript(new Script(type, lang, "ctx._source.hobbyList.removeIf(item -> item.id == params.id)", paramsMap));
updateByQueryRequest.setQuery(new TermQueryBuilder("name.keyword", "曹尼玛"));
updateByQueryRequest.setBatchSize(100);
updateByQueryRequest.setAbortOnVersionConflict(false);
this.getResponseBySearchRequest(updateByQueryRequest);
}
把名字叫王尼玛的童鞋,看美女的爱好强制改为看比赛:
public void testNestedUpdate() throws Exception {
UpdateByQueryRequest updateByQueryRequest = new UpdateByQueryRequest("student");
Map<String, Object> paramsMap = new HashMap<String, Object>(16);
paramsMap.put("id", 102);
paramsMap.put("name","看比赛");
ScriptType type = ScriptType.INLINE;
String lang = "painless";
String idOrCode = "for(e in ctx._source.scoreList){if (e.id == params.id) {e.name = params.name;}}";
updateByQueryRequest.setScript(new Script(type, lang, idOrCode, paramsMap));
updateByQueryRequest.setQuery(new TermQueryBuilder("name.keyword", "王尼玛"));
updateByQueryRequest.setBatchSize(100);
updateByQueryRequest.setAbortOnVersionConflict(false);
this.getResponseBySearchRequest(updateByQueryRequest);
}
执行UpdateByQuery 请求获取返回结果的方法如下,setBatchSize 分批执行,setAbortOnVersionConflict 忽略乐观锁版本号冲突。
private BulkByScrollResponse getResponseBySearchRequest(UpdateByQueryRequest searchRequest) {
BulkByScrollResponse searchResponse = elasticSearchConfig.getObject().updateByQuery(searchRequest, RequestOptions.DEFAULT);
return searchResponse;
}
上面四种是常用的ES UpdateByQuery Java Api的基本常用写法,对于这种Api怎么使用,就不要占用自己太长时间,多关注设计,然后让设计被成功实现,过程优雅一点,围绕软件的核心——为用户解决领域相关的问题的能力。