我添加了一个本机脚本,在添加新文档时作为转换运行。我需要文档ID,但它不作为脚本参数的一部分传入。只有_source作为参数传入,而不是_id值。有没有办法让ElasticSearch传入_id?或某种方式阅读它...不知何故?
下面是一个人为的ElasticSearch本机脚本示例,它演示了我正在谈论的内容。 setNextVar()由ElasticSearch和" ctx"传入了对象。该值是一个只有一个对象的Map,即_source对象。
但默认情况下,Elastic Key不会传入_id键/值对。我希望有一个原因,可以在映射json中配置本机脚本,告诉它传入文档ID。
public class ExampleNativeScript extends AbstractExecutableScript {
/**
* Factory class that serves native script to ElasticSearch
*/
public static class Factory extends AbstractComponent implements NativeScriptFactory {
@Inject
public Factory(Settings settings, String prefixSettings) {
super(settings, prefixSettings);
}
@Override
public ExecutableScript newScript(@Nullable Map<String, Object> params) {
return new ExampleNativeScript(params);
}
}
private final Map<String, Object> variables;
private Map ctx = null;
private Map source = null;
public ExampleNativeScript(Map<String, Object> params) {
this.variables = params;
}
@Override
public void setNextVar(String name, Object value) {
variables.put(name, value);
if (name.equals("ctx")) {
ctx = (Map<String, LinkedHashMap>) value;
source = (Map<String, LinkedHashMap>) ctx.get("_source");
} else {
//never gets here
System.out.println("Unexpected variable");
}
}
@Override
public Object run() {
//PROBLEM: ctx only has _source. _id does not get passed in so this blows chunks
String documentId = ctx.get("_id").toString();
System.out.println(documentId);
return ctx;
}
}
答案 0 :(得分:0)
所以只是在ElasticSearch源代码中进行了一些挖掘,发现它的硬编码仅传递_source字段,而没有传递其他ctx级别字段。所以没有办法让/ config ElasticSearch传入_id
以下是调用本机脚本的DocumentMapper.transformSourceAsMap()
和setNextVar()
函数的run()
函数。它表明在ctx映射中唯一放置的是_source字段。
public Map<String, Object> transformSourceAsMap(Map<String, Object> sourceAsMap) {
try {
// We use the ctx variable and the _source name to be consistent with the update api.
ExecutableScript executable = scriptService.executable(language, script, scriptType, ScriptContext.Standard.MAPPING, parameters);
Map<String, Object> ctx = new HashMap<>(1);
ctx.put("_source", sourceAsMap);
executable.setNextVar("ctx", ctx);
executable.run();
ctx = (Map<String, Object>) executable.unwrap(ctx);
return (Map<String, Object>) ctx.get("_source");
} catch (Exception e) {
throw new ElasticsearchIllegalArgumentException("failed to execute script", e);
}
}