【问题标题】:How to get document id (_id) inside an Elasticsearch native script如何在 Elasticsearch 本机脚本中获取文档 ID (_id)
【发布时间】:2015-07-28 00:25:03
【问题描述】:

我有一个本地脚本,在添加新文档时作为转换运行。我需要文档 ID,但它没有作为脚本参数的一部分传入。只有 _source 作为参数传入,而不是 _id 值。有什么方法可以让 ElasticSearch 传入 _id?或者以某种方式阅读它……以某种方式?

下面是一个人为的 ElasticSearch 原生脚本示例,它演示了我在说什么。 setNextVar() 由 ElasticSearch 调用并传入“ctx”对象。该值是一个 Map,其中只有一个对象,即 _source 对象。

但是ElasticSearch默认不传入_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;
    }
}

【问题讨论】:

  • 实际上,由于您使用的是AbstractExecutableScript,如果记忆对我有用,_id 字段可能仍然不存在(例如,如果在现已弃用的转换中使用该脚本)。也许这就是他们没有通过它的原因?

标签: plugins elasticsearch transform


【解决方案1】:

所以刚刚在 ElasticSearch 源中进行了一些挖掘,发现它的硬编码只传递了 _source 字段,而没有传递其他 ctx 级别的字段。因此无法获取/配置 ElasticSearch 以传入 _id

下面是调用本机脚本的setNextVar()run() 函数的DocumentMapper.transformSourceAsMap() 函数。它表明 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);
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-12-11
    • 1970-01-01
    • 2014-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-03
    • 1970-01-01
    相关资源
    最近更新 更多