如何通过JSON设置Elasticsearch SearchRequest的查询?

10

Elasticsearch: 6.1.2

我有一个JSON格式的查询输入,希望使用高级Java API根据这个查询数据构建一个搜索请求。

String jsonQuery = "..."
SearchRequest searchRequest = new SearchRequest()
SearchSourceBuilder builder = ?
searchRequest.source(builder);

我尝试通过以下方式构建生成器:

SearchSourceBuilder.fromXContent(XContentType.JSON.xContent().createParser(NamedXContentRegistry.EMPTY, query));

但这会产生以下错误:

Caused by: org.elasticsearch.ElasticsearchException: namedObject is not supported for this parser at org.elasticsearch.common.xcontent.NamedXContentRegistry.parseNamedObject(NamedXContentRegistry.java:129) ~[elasticsearch-6.1.2.jar:6.1.2] at org.elasticsearch.common.xcontent.support.AbstractXContentParser.namedObject(AbstractXContentParser.java:402) ~[elasticsearch-6.1.2.jar:6.1.2] at org.elasticsearch.index.query.AbstractQueryBuilder.parseInnerQueryBuilder(AbstractQueryBuilder.java:313) ~[elasticsearch-6.1.2.jar:6.1.2] at org.elasticsearch.search.builder.SearchSourceBuilder.parseXContent(SearchSourceBuilder.java:1003) ~[elasticsearch-6.1.2.jar:6.1.2] at org.elasticsearch.search.builder.SearchSourceBuilder.fromXContent(SearchSourceBuilder.java:115) ~[elasticsearch-6.1.2.jar:6.1.2]

3个回答

10

我现在使用以下方式生成SearchSourceBuilder:

String query = "..."
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
SearchModule searchModule = new SearchModule(Settings.EMPTY, false, Collections.emptyList());
try (XContentParser parser = XContentFactory.xContent(XContentType.JSON).createParser(new NamedXContentRegistry(searchModule
            .getNamedXContents()), query)) {
    searchSourceBuilder.parseXContent(parser);
}

TFFY @Jotschi 你刚刚让我度过了美好的星期五。 - ndtreviv
2
@ndtreviv,我不再使用这种方法了。使用普通的JSON和REST更加灵活。 - Jotschi
哦,当然,如果你想重构世界的话。毕竟,今天是星期五。 - ndtreviv
我看到很多例子使用new NamedXContentRegistry(ClusterModule.getNamedXWriteables())作为注册中心,但这对我不起作用。这个可以。非常感谢。 - nonzaprej

1

我也遇到了同样的问题。我们正在从ES 1.4.4升级到ES 6.4.2,我使用了ES提供的Java高级Rest客户端来执行在ES中创建/更新/删除操作。我找不到一种简单的方法将先前ES版本中使用的查询JSON转换为适当的searchRequest,以便使用高级Rest客户端。以下是我最终使用的内容。

import org.elasticsearch.client.Response;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.Request;

public static Response executeGetRequest(RestHighLevelClient client,
            String api, String body) throws Exception {

            Request request = new Request("GET", api);
            if(body != null && !body.isEmpty()) {
                request.setJsonEntity(body);
            }            
            Response response = client.getLowLevelClient()
                    .performRequest(request);
            if (response == null) {
                throw new Exception(
                        "Get request have failed");
            }
            return response;        
    }

0
在createParser方法中,将第一个参数NamedXContentRegistry.EMPTY替换为JsonXContent.jsonXContent

createParser仅接受NamedXContentRegistry - 你的建议不会编译,因为该值是JsonXContent。 - Jotschi
似乎在v6.2中可用 https://github.com/elastic/elasticsearch/blob/6.2/server/src/main/java/org/elasticsearch/common/xcontent/json/JsonXContent.java - Aman B
你可以在这里查看测试用例 https://github.com/elastic/elasticsearch/blob/6.2/server/src/test/java/org/elasticsearch/search/builder/SearchSourceBuilderTests.java - Aman B
那是来自ESTestCase完全不同的createParser方法。 - Jaap

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接