如何使用Elasticsearch插件定义的过滤器

时间:2015-04-21 22:14:53

标签: elasticsearch elasticsearch-plugin

我为Elasticsearch创建了一个插件,并已成功安装(http://localhost:9200/_nodes/plugins/显示已安装它。)但我似乎无法在查询中使用它 - 我只会收到错误。 " ScriptException [已禁用[groovy]的动态脚本]"。好像我需要一个不同的lang设置。但是我已经尝试过'' java'。没有快乐。我试过郎:表达。然后我得到" ExpressionScriptCompilationException [表达式"中的未知变量[maxmind]。如何访问我创建的插件?或者我是否需要做更多的事情才能注册?

我一直在关注这个优秀的指南: https://github.com/imotov/elasticsearch-native-script-example

但它没有说明应该如何编写查询。

我的AbstractPlugin:

package org.elasticsearch.plugin.maxmind;

import java.util.Collection;

import org.elasticsearch.common.collect.Lists;
import org.elasticsearch.common.inject.Module;
import org.elasticsearch.plugins.AbstractPlugin;
import org.elasticsearch.script.ScriptModule;

import org.elasticsearch.plugin.maxmind.GeoLoc;

public class MaxMind extends AbstractPlugin {
    @Override public String name() {
        return "maxmind";
    }

    @Override public String description() {
        return "Plugin to annotate ip addresses with maxmind geo data";
    }

    // Thanks https://github.com/imotov/elasticsearch-native-script-example
    public void onModule(ScriptModule module) {
        module.registerScript("geoloc", GeoLoc.Factory.class);
    }
}

请注意名称" geoloc"。这是我在查询中使用的名称吗?

我的GeoLoc模块:

package org.elasticsearch.plugin.maxmind;

import java.util.HashMap;
import java.util.Map;

import org.elasticsearch.script.ScriptException;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.xcontent.support.XContentMapValues;
import org.elasticsearch.index.fielddata.ScriptDocValues;
import org.elasticsearch.script.AbstractSearchScript;
import org.elasticsearch.script.ExecutableScript;
import org.elasticsearch.script.NativeScriptFactory;

public class GeoLoc extends AbstractSearchScript {

    public static class Factory implements NativeScriptFactory {

        // called on every search on every shard
        @Override
        public ExecutableScript newScript
            (@Nullable Map<String, Object> params)
        {
            String fieldName = params == null ? null:
                XContentMapValues.nodeStringValue(params.get("field"), null);
            if (fieldName == null) {
                throw new ScriptException("Missing field parameter");
            }
            return new GeoLoc(fieldName);
        }
    }

    private final String fieldName;

    private GeoLoc(String fieldName) {
        this.fieldName = fieldName;
    }

    @Override
    public Object run() {
        ScriptDocValues docValue = (ScriptDocValues) doc().get(fieldName);
        if (docValue != null && !docValue.isEmpty()) {
            // TODO: real geolocation here
            HashMap fakeloc = new HashMap<String, String>();
            fakeloc.put("lat", "1.123");
            fakeloc.put("lon", "44.001");
            fakeloc.put("basedon", docValue);
            return fakeloc;
        }
        return false;
    }
}

我的查询:

{
    "_source": [
        "uri",
        "user_agent",
        "server_ip",
        "server_port",
        "client_ip",
        "client_port"
    ],
    "query": {
        "filtered": {
            "filter": {}
        }
    },
    "script_fields": {
        "test1": {
            "params": {
                "field": "client_ip"
            },
            "script": "geoloc"  // is this right?
        }
    },
    "size": 1
}

1 个答案:

答案 0 :(得分:5)

您应该能够使用脚本指定lang: "native",任何用Java编写并在registerScript注册的脚本都是“本机”类型。