我正在开发一个 springboot 项目,并且在使用 ElasticSearch 时遇到了一些问题。 用户将一些 JSON 格式的 elasticsearch DSL 查询字符串放入数据库中,它们对我来说是黑匣子。我需要做的是获取查询字符串并使用它们,以便在elasticsearch中搜索信息。
在Python中,DSL可以是这样的参数:
body = {
"query":{
"match_all":{}
}
}
es.search(index="my_index",doc_type="test_type",body=body)
如何在不知道字符串详细信息的情况下仅使用 Java 中的 JSON 格式查询来执行搜索?
我相信在现代 ES 客户端库中有两种方法可以做到这一点。我自己没有尝试过,但第一个似乎非常简单。
第一个是使用低级客户端:
Request request = new Request("POST", "/index/_search");
request.setJsonEntity(jsonString);
Response response = client.performRequest(request);
似乎只需将 JSON 作为字符串推送到 setJsonEntity 中就足够了,并且您已经设置好了。
第二种是使用高级客户端,这会变得很棘手,尽管它可以提供更强大的 API。你可能知道,elasticsearch 有 XContent 的概念,它是不同格式(包括 JSON)的序列化/反序列化。理论上,可以创建 JsonXContentParser,然后可以使用它来实例化 SearchSourceBuilder:
SearchSourceBuilder.fromXContent(jsonXContentParser);
问题只是 JsonXContentParser 需要实例化多个参数,并且我不确定如何正确创建这些依赖项。
public SearchResponse search(String indexName, String source) {
try {
Request request = new Request("GET", String.format("/%s/_search", indexName));
request.setJsonEntity(source);
Response response = searchEsClient.getLowLevelClient().performRequest(request);
String responseBody = EntityUtils.toString(response.getEntity());
XContentParser parser =
JsonXContent.jsonXContent.createParser(
NamedXContentRegistry.EMPTY,
DeprecationHandler.THROW_UNSUPPORTED_OPERATION,
responseBody);
return SearchResponse.fromXContent(parser);
} catch (IOException e) {
log.error(String.format("dsl query fail:%s", indexName, e.getMessage()), e);
throw new GlobalException(e);
}
}
这样你就可以从SearchResponse中获取SearchHit
val searchHits = response.hits.filter { it.sourceAsMap != null }