3

I'm upgrading an Elasticsearch plugin from version 2.4.0 to 5.4.0. This plugin implements a custom query but with the new changes on Elasticsearch Java Api I'm a little confused in how to register the new query. I search in Elasticsearch site and I found that I must implement the SearchPlugin interfaces and override the method getQueriesbut I'm still confuse and how I do that. Any help?

1 Answers1

2

You need something like this (java8):

public class MyQueryPlugin extends Plugin implements SearchPlugin {

    @Override public List<QuerySpec<?>> getQueries() {
        return Arrays.asList(
                new QuerySpec<>("my_query", MyQueryBuilder::new, MyQueryBuilder::fromXContent)
        );
    }
}

Or this (java 7):

public class MyQueryPlugin extends Plugin implements SearchPlugin {

    @Override
    public List<QuerySpec<?>> getQueries() {
        return Arrays.asList(new QuerySpec<>(
                "my_query",
                new Writeable.Reader<MyQueryBuilder>() {
                    @Override
                    public MyQueryBuilder read(StreamInput in) throws IOException {return new MyQueryBuilder(in);}
                },
                new QueryParser<MyQueryBuilder>() {
                    @Override
                    public Optional<MyQueryBuilder> fromXContent(QueryParseContext parseContext) throws IOException {return MyQueryBuilder.fromXContent(parseContext);}
                })
        );
    }
}

MyQueryBuilder will probably extend AbstractQueryBuilder<MyQueryBuilder>. Most other ES-provided queries extend this - they're a good source to copy from.

MyQueryBuilder::fromXContent is the other change that caught me out - it should do the same as org.elasticsearch.index.query.QueryParser#parse(QueryParseContext parseContext) from 2.x.

MyQueryPlugin is what you'd reference in your plugin-descriptor.properties like:

description=my-query example
version=1.0.0
name=my-query
java.version=1.8
elasticsearch.version=5.4.0
classname=com.example.MyQueryPlugin
Tim Helmstedt
  • 2,744
  • 1
  • 20
  • 10
  • Thanks but didn't work for me. I search in Elasticsearch code and I found that the `QuerySpec` need 3 params: the name of the query, the `Writeable.Reader` interface and the `QueryParser`. The `Writeable.Reader` interface is what I don't know where find it. Must I create one or no? I suppose that I must use one from Elasticsearch but I'm lost here. – Daniel Pupo Ricardo May 29 '17 at 14:17
  • You need to create one on the fly. `MyQueryBuilder::new` is actually expanding to what you need as it's an `@FunctionalInterface`. I'll edit the answer with a non-java8 example. You can find a lot of examples of `QuerySpec` in `org.elasticsearch.search.SearchModule#registerQueryParsers` – Tim Helmstedt May 30 '17 at 04:25
  • Thanks, I spend days to find a solution for my problem. Thanks a lot again. – Daniel Pupo Ricardo May 30 '17 at 13:52