英文:
How to use Elasticsearch API ScriptQueryBuilder
问题
我使用Elasticsearch 6.8.12版本,我需要在Java中添加一个update by query的API,我查阅了ES文档并了解到ScriptQueryBuilder可以构建脚本,但我不知道如何使用它,我在Google上搜索了但没有找到任何有用的教程。
分享我目前了解的内容:
- 我们可以使用
_update_by_query
来更新,就像MySQL中的set extra=test where user='kimchy'
,参考es update by query:
POST twitter/_update_by_query
{
"script": {
"source": "ctx._source['extra'] = 'test'",
"lang": "painless"
},
"query": {
"term": {
"user": "kimchy"
}
}
}
ScriptQueryBuilder
可以生成脚本查询的JSON,依赖:
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>6.8.12</version>
</dependency>
我尝试了下面的代码,但运行失败:
public String generateUpdateQuery() {
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
Map<String, Object> params = new HashMap<>(16);
params.put("user","kimchy");
Script script = new Script(Script.DEFAULT_SCRIPT_TYPE, null, null, params);
ScriptQueryBuilder scriptQueryBuilder = QueryBuilders.scriptQuery(script);
System.out.println(scriptQueryBuilder.toString());
return null;
}
我的需求:
我需要使用ScriptQueryBuilder
和QueryBuilders
来生成脚本JSON,ES API为_update_by query
。
谢谢!
英文:
I use Elasticsearch 6.8.12, i need to add a update by query API in Java, i check docs in ES and know ScriptQueryBuilder can build script but i don't know how to use it, i searched in google and couldn't found any usable tutorial.
Share what i know currently:
- we can use
_update_by_query
to update like Mysqlset extra= test where user='kimchy'
, refer to
es update by query
POST twitter/_update_by_query
{
"script": {
"source": "ctx._source.['extra'] = 'test'",
"lang": "painless"
},
"query": {
"term": {
"user": "kimchy"
}
}
}
ScriptQueryBuilder
can generate script query json,
dependency:
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>6.8.12</version>
</dependency>
I tried below code but it run failed:
public String generateUpdateQuery() {
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
Map<String, Object> params = new HashMap<>(16);
params.put("user","kimchy");
Script script = new Script(Script.DEFAULT_SCRIPT_TYPE, null, null, params);
ScriptQueryBuilder scriptQueryBuilder = QueryBuilders.scriptQuery(script);
System.out.println(scriptQueryBuilder.toString());
return null;
}
My requirement:
I need to generate script json using ScriptQueryBuilder
QueryBuilders
, the ES API is _update_by query
Thanks!
答案1
得分: 0
解决方案:
对于 SQL 查询部分:
{
"query": {
"term": {
"user": "kimchy"
}
},
"script": {
"source": "ctx._source.extra = \"test\";",
"lang": "painless"
}
}
使用 ScriptQueryBuilder
的代码部分:
public String generateUpdateByQuery() {
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
boolQueryBuilder.filter(QueryBuilders.termQuery("user", "kimchy"));
StringBuilder sb = new StringBuilder();
sb.append(String.format("ctx._source.%s = %s;", "extra", String.format("\"%s\"", "test")));
// 如果没有参数,保持为空,在 Script 中需要
Map<String, Object> params = new HashMap<>(16);
Script script = new Script(Script.DEFAULT_SCRIPT_TYPE, "painless", sb.toString(), params);
ScriptQueryBuilder scriptQueryBuilder = QueryBuilders.scriptQuery(script);
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(boolQueryBuilder);
// 处理 SQL 部分
JSONObject scriptOuter = JSON.parseObject(scriptQueryBuilder.toString());
JSONObject scriptJson = (JSONObject)scriptOuter.get("script");
JSONObject queryJson = JSON.parseObject(searchSourceBuilder.toString());
scriptJson.putAll(queryJson);
scriptJson.remove("boost");
// 查询:
return scriptJson.toJSONString();
}
如果你的查询包含参数,像这样:
"script": {
"source": "ctx._source.extra = params.extraVal;",
"lang": "painless",
"params": {
"extraVal": "test"
}
}
那么在上面的参数映射 params
中设置参数:
Map<String, Object> params = new HashMap<>(16);
params.put("extraVal", "test");
Script script = new Script(Script.DEFAULT_SCRIPT_TYPE, "painless", sb.toString(), params);
英文:
Solution:
For sql:
{
"query": {
"term": {
"user": "kimchy"
}
},
"script": {
"source": "ctx._source.extra = \"test\";",
"lang": "painless"
}
}
Code using ScriptQueryBuilder
:
public String generateUpdateByQuery() {
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
boolQueryBuilder.filter(QueryBuilders.termQuery("user", "kimchy"));
StringBuilder sb = new StringBuilder();
sb.append(String.format("ctx._source.%s = %s;", "extra", String.format("\"%s\"","test")));
// if no params, keep it empty, it required in Script
Map<String, Object> params = new HashMap<>(16);
Script script = new Script(Script.DEFAULT_SCRIPT_TYPE, "painless", sb.toString(), params);
ScriptQueryBuilder scriptQueryBuilder = QueryBuilders.scriptQuery(script);
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(boolQueryBuilder);
// deal sql
JSONObject scriptOuter = JSON.parseObject(scriptQueryBuilder.toString());
JSONObject scriptJson = (JSONObject)scriptOuter.get("script");
JSONObject queryJson = JSON.parseObject(searchSourceBuilder.toString());
scriptJson.putAll(queryJson);
scriptJson.remove("boost");
// query:
return scriptJson.toJSONString()
}
If your query contains params like that:
"script": {
"source": "ctx._source.extra = params.extraVal;",
"lang": "painless"
"params": {
"extraVal":"test"
}
}
Then set params in the above map params
Map<String, Object> params = new HashMap<>(16);
params.put("extraVal","test")
Script script = new Script(Script.DEFAULT_SCRIPT_TYPE, "painless", sb.toString(), params);
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论