使用 ElasticSearch 的 script_upsert 创建文档

Using ElasticSearch's script_upsert to create a document

根据官方文档Update API - Upserts one can use scripted_upsert in order to handle update (for existing document) or insert (for new document) form within the script. The thing is they never show how the script should look to do that. The 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);

当 "testUser" 文档不存在时,我得到以下异常:
DocumentMissingException[[user][testUser]: document missing

如何使 scriptUpsert 从 Java 代码运行?

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,2,3,55.

而在您的情况下,您缺少 "upsert": {} 部分。

正如 Andrei 所建议的,我遗漏了更新插入部分,将函数更改为:

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);
}

修复它。