转换一个Java映射到SearchSourceBuilder Elasticsearch 7.2 J

2019-10-16 13:48发布

我写的是从客户需要的搜索请求并将其提交给Elasticsearch高级API REST应用程序(javax.ws.rs)。 我想客户端(基于浏览器的JavaScript居多),以能够撰写使用Elasticsearch REST API说明他们的搜索。

其余部分结束点的定义如下:

@Path("list")
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response list(Map<String, Object> req) {
  ...

下面的代码将实现一个安全层功能,然后传递给SearchRequest对象几乎不变的查询。 所以我不希望建立使用QueryBuilders这里查询。

我曾尝试在说明这篇文章 ,但它不工作。 我认为createParser方法已经改变,因为这个例子写。 如果有人可以审查这一点,并建议将非常感激的解决方案。

更新:使用ES 7.2我想出了下面的代码。 已有的API并不是所有的我明白了许多变化,但这里是什么似乎像它应该工作。

        XContentBuilder xcb = XContentFactory.contentBuilder(Requests.CONTENT_TYPE);
        xcb.map(req);
        String json = Strings.toString(xcb);

        XContentParser parser = JsonXContent.jsonXContent.createParser(
                NamedXContentRegistry.EMPTY, LoggingDeprecationHandler.INSTANCE, json);
        SearchSourceBuilder ssb = new SearchSourceBuilder();
        ssb.parseXContent(parser);

        SearchRequest sr = new SearchRequest(Log.INDEX);
        sr.source(ssb);

        SearchResponse resp = client.search(sr, RequestOptions.DEFAULT);

我得到一个IOException关闭调用的parseXContent 。 与调试器寻找字符串json中有不可打印的字符。 有什么建议么?

Answer 1:

我发现,工作的代码模式,它似乎有点令人费解,但逻辑。 没有文档的任何地方,这将导致你这个。 这是从张贴在这里和那里的留言板一些片段拼凑起来。

    try {

        // convert the Map into a JSON string to parse.  Alternatively
        // you could just take the string directly from the HTTP request
        // but the Map form makes it easy to manipulate. 

        XContentBuilder xcb = XContentFactory.jsonBuilder();
        xcb.map(req);
        String json = Strings.toString(xcb);

        // Create an XContentParser and borrow a NamedXContentRegistry from
        // the SearchModule class.  Without that the parser has no way of
        // knowing the query syntax.

        SearchModule sm = new SearchModule(Settings.EMPTY, false, Collections.emptyList());
        XContentParser parser = XContentFactory.xContent(XContentType.JSON)
                .createParser(new NamedXContentRegistry(sm.getNamedXContents()),
                              LoggingDeprecationHandler.INSTANCE,
                              json);

        // Finally we can create our SearchSourceBuilder and feed it the
        // parser to ingest the request.  This can throw and IllegalArgumentException
        // if something isn't right with the JSON that we started with.

        SearchSourceBuilder ssb = new SearchSourceBuilder();
        ssb.parseXContent(parser);

        // Now create a search request and use it

        SearchRequest sr = new SearchRequest(Log.INDEX);
        sr.source(ssb);
        SearchResponse resp = client.search(sr, RequestOptions.DEFAULT);

我曾与来​​自客户端的数量不同的JSON的查询测试这一点,他们似乎都在上班的路上直接REST API会。 下面是一个例子:

{
    from: 0,
    size: 1000,
    query: {
      match_all: { boost: 1 }
    },
    sort: [
      { timestamp: { 'order': 'asc' } }
    ]
}

希望这篇文章将节省有人从痛苦的搜索我经历了别人。 我希望从任何人谁可以建议这样做的更好的办法任何评论。



文章来源: Converting a Java Map to a SearchSourceBuilder Elasticsearch 7.2 Java High Level API