繁体   English   中英

将 Java Map 转换为 SearchSourceBuilder Elasticsearch 7.2 Java 高级 API

[英]Converting a Java Map to a SearchSourceBuilder Elasticsearch 7.2 Java High Level API

我正在编写一个 REST 应用程序 (javax.ws.rs),它接收来自客户端的搜索请求并将它们提交给 Elasticsearch 高级 API。 我希望客户端(主要是基于浏览器的 javascript)能够使用 Elasticsearch REST API 指令编写他们的搜索。

REST 端点定义如下:

@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);

我从对parseXContent的调用中得到一个 IOException 。 使用调试器查看字符串json有不可打印的字符。 有什么建议?

我发现了一个有效的代码模式,它看起来有点复杂但合乎逻辑。 任何地方都没有任何文档可以引导您做到这一点。 这是从到处张贴在留言板上的一些片段拼凑而成的。

    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' } }
    ]
}

希望这篇文章能让其他人免于我经历的痛苦搜索。 如果有人提出更好的方法,我将不胜感激。

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

SearchSourceBuilder ssb = new SearchSourceBuilder();
ssb.query(QueryBuilders.wrapperQuery(json));

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM