1

在 Elasticsearch 2.x 中,我们source(Map)用来初始化 aSearchRequest的源:

SearchRequest searchRequest = new SearchRequest();
searchRequest.source((Map<?,?>) request.get("search_request"));

在 Elasticsearch 5 中,所有source(...)方法都消失了,取而代之的是一个 take SearchSourceBuilder。记录了这么多。

但是我到底如何将 a 转换Map为 a SearchSourceBuilder?那里似乎没有任何有用的工厂方法,我已经搜索了其他方法Map,似乎没有任何东西跳出来。

4

1 回答 1

2

您强调的问题已被报告,但由于这个原因,这不再可能。

您可以阅读与这一重大变化相关的完整故事,但总而言之,在 ES 2.x 中,协调节点(即接收查询的节点)会将查询的解析委托给每个分片,这不仅是浪费资源(主要是 CPU 周期),但也有一些其他缺点,即不可能在一个地方优化查询。

在 ES 5 中,他们决定协调节点执行一次解析,然后将解析后的查询发送到每个分片。如果您阅读我链接到的那篇博客文章,您会发现这应该是一个很大的改进。当然,这意味着您无法再使用该SearchRequest.source(Map)方法。

更新

该方法的原始源代码source(Map)如下所示:

public SearchRequest source(Map source) {
    try {
        XContentBuilder builder = XContentFactory.contentBuilder(Requests.CONTENT_TYPE);
        builder.map(source);
        return source(builder);
    } catch (IOException e) {
        throw new ElasticsearchGenerationException("Failed to generate [" + source + "]", e);
    }
}

没有什么能阻止您使用该代码在应用程序代码中进行转换。

我还没有测试过,但是你应该可以创建一个SearchSourceBuilder这样的:

SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();

// from Map to XContent
XContentBuilder builder = ... // see above
// from XContent to JSON
String json = new String(builder.getBytes(), "UTF-8");
// use JSON to populate SearchSourceBuilder
JsonXContent parser = createParser(JsonXContent.jsonXContent, json));
sourceBuilder.parseXContent(new QueryParseContext(parser));
于 2017-01-20T04:21:25.583 回答