使用ElasticSearch的script_upsert创建文档

时间:2016-08-02 11:45:08

标签: java elasticsearch upsert elasticsearch-java-api

根据官方文档Update API - Upserts,可以使用scripted_upsert来处理脚本中的更新(针对现有文档)或插入(针对新文档)表单。问题是他们从未表明脚本应该如何做到这一点。 Java - Update API没有关于ScriptUpsert使用的任何信息。

这是我使用的代码:

//My function to build and use the upsert
public void scriptedUpsert(String key, String parent, String scriptSource, Map<String, ? extends Object> parameters) {
    Script script = new Script(scriptSource, ScriptType.INLINE, null, parameters);
    UpdateRequest request = new UpdateRequest(index, type, key);
    request.scriptedUpsert(true);
    request.script(script);
    if (parent != null) {
        request.parent(parent);
    }
    this.bulkProcessor.add(request);
}

//A test call to validate the function
String scriptSource = "if (!ctx._source.hasProperty(\"numbers\")) {ctx._source.numbers=[]}";
Map<String, List<Integer>> parameters = new HashMap<>();
List<Integer> numbers = new LinkedList<>();
numbers.add(100);
parameters.put("numbers", numbers);

bulk.scriptedUpsert("testUser", null, scriptSource, parameters);

我在&#34; testUser&#34;时遇到以下异常。文件不存在:
DocumentMissingException[[user][testUser]: document missing

如何使用Java代码使scriptUpsert工作?

2 个答案:

答案 0 :(得分:3)

这是XMLHttpRequest cannot load http://finance.app/jwt/access_token. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8080' is therefore not allowed access. 命令的样子(及其脚本):

OPTIONS /jwt/access_token HTTP/1.1
Host: finance.app
Connection: keep-alive
Access-Control-Request-Method: POST
Origin: http://localhost:8080
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.82 Safari/537.36
Access-Control-Request-Headers: access-control-allow-origin, content-type
Accept: */*
Referer: http://localhost:8080/
Accept-Encoding: gzip, deflate, sdch
Accept-Language: pt-BR,pt;q=0.8,en-US;q=0.6,en;q=0.4

如果调用上述命令且索引不存在,它将与新文档中的scripted_upsert值一起创建它。如果再次使用完全相同的命令,POST /sessions/session/1/_update { "scripted_upsert": true, "script": { "inline": "if (ctx.op == \"create\") ctx._source.numbers = newNumbers; else ctx._source.numbers += updatedNumbers", "params": { "newNumbers": [1,2,3], "updatedNumbers": [55] } }, "upsert": {} } 值将变为newNumbers

在你的情况下,你遗漏了numbers部分。

答案 1 :(得分:0)

正如Andrei所说,我错过了upsert部分,将函数更改为:

public void scriptedUpsert(String key, String parent, String scriptSource, Map<String, ? extends Object> parameters) {
    Script script = new Script(scriptSource, ScriptType.INLINE, null, parameters);
    UpdateRequest request = new UpdateRequest(index, type, key);
    request.scriptedUpsert(true);
    request.script(script);
    request.upsert("{}"); // <--- The change
    if (parent != null) {
        request.parent(parent);
    }
    this.bulkProcessor.add(request);
}

修复它。