从 JSON 数据创建 API 对象
编辑从 JSON 数据创建 API 对象
编辑在使用 Elasticsearch 进行应用程序开发的常见工作流程中,会使用 Kibana 开发者控制台来交互式地准备和测试查询、聚合、索引映射和其他复杂的 API 调用。这将生成可用于应用程序的工作 JSON 代码片段。
由于将这些 JSON 代码片段转换为 Java 代码可能既耗时又容易出错,因此 Java API 客户端中的大多数数据类都可以从 JSON 文本加载:对象构建器具有 withJson()
方法,这些方法可从原始 JSON 中填充构建器。这也允许您将动态加载的 JSON 与对象的编程构建相结合。
在后台,withJson()
方法调用对象的反序列化器。因此,JSON 文本的结构和值类型必须与目标数据结构正确匹配。使用 withJson()
保留了 Java API 客户端的强类型保证。
示例
编辑从资源文件加载索引定义
编辑考虑一个包含索引定义的资源文件 some-index.json
{ "mappings": { "properties": { "field1": { "type": "text" } } } }
您可以按如下方式从该定义创建索引
InputStream input = this.getClass() .getResourceAsStream("some-index.json"); CreateIndexRequest req = CreateIndexRequest.of(b -> b .index("some-index") .withJson(input) ); boolean created = client.indices().create(req).acknowledged();
从 JSON 文件导入文档
编辑同样,您可以从数据文件读取要存储在 Elasticsearch 中的文档
FileReader file = new FileReader(new File(dataDir, "document-1.json")); IndexRequest<JsonData> req; req = IndexRequest.of(b -> b .index("some-index") .withJson(file) ); client.index(req);
创建结合 JSON 和编程构建的搜索请求
编辑您可以将 withJson()
与对 setter 方法的常规调用结合使用。以下示例从 String
加载搜索请求的查询部分,并以编程方式添加聚合。
Reader queryJson = new StringReader( "{" + " \"query\": {" + " \"range\": {" + " \"@timestamp\": {" + " \"gt\": \"now-1w\"" + " }" + " }" + " }" + "}"); SearchRequest aggRequest = SearchRequest.of(b -> b .withJson(queryJson) .aggregations("max-cpu", a1 -> a1 .dateHistogram(h -> h .field("@timestamp") .calendarInterval(CalendarInterval.Hour) ) .aggregations("max", a2 -> a2 .max(m -> m.field("host.cpu.usage")) ) ) .size(0) ); Map<String, Aggregate> aggs = client .search(aggRequest, Void.class) .aggregations();
从 JSON 字符串加载查询。 |
|
添加聚合。 |
|
由于这是一个聚合,我们不关心结果文档并将它们的 target 类设置为 |
从多个 JSON 代码片段创建搜索请求
编辑withJson()
方法是部分反序列化器:从 JSON 加载的属性将设置属性值或替换先前的属性值,但不会重置 JSON 输入中未找到的其他属性。您可以使用此功能组合多个 JSON 代码片段以构建复杂的搜索请求。在下面的示例中,我们组合了选择某些文档的查询和对该查询结果运行的聚合的单独定义。
Reader queryJson = new StringReader( "{" + " \"query\": {" + " \"range\": {" + " \"@timestamp\": {" + " \"gt\": \"now-1w\"" + " }" + " }" + " }," + " \"size\": 100" + "}"); Reader aggregationJson = new StringReader( "{" + " \"size\": 0, " + " \"aggregations\": {" + " \"hours\": {" + " \"date_histogram\": {" + " \"field\": \"@timestamp\"," + " \"interval\": \"hour\"" + " }," + " \"aggregations\": {" + " \"max-cpu\": {" + " \"max\": {" + " \"field\": \"host.cpu.usage\"" + " }" + " }" + " }" + " }" + " }" + "}"); SearchRequest aggRequest = SearchRequest.of(b -> b .withJson(queryJson) .withJson(aggregationJson) .ignoreUnavailable(true) ); Map<String, Aggregate> aggs = client .search(aggRequest, Void.class) .aggregations();
请注意,当 JSON 代码片段具有某些公共属性时,顺序很重要:就像以编程方式设置属性值一样,为属性设置的最后一个值会覆盖先前的值。
上面示例的源代码可以在 Java API 客户端测试 中找到。