Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[8.1] Raw json support (#200) #205

Merged
merged 1 commit into from
Mar 17, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,6 @@ gradle-app.setting
*.iml

.ci/output

# HTML files produced by the docs build
html_docs
1 change: 1 addition & 0 deletions docs/index.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ include::installation.asciidoc[]
include::connecting.asciidoc[]
include::migrate.asciidoc[]
include::api-conventions.asciidoc[]
include::loading-json.asciidoc[]
include::javadoc-and-source.asciidoc[]

include::{elasticsearch-root}/docs/java-rest/low-level/index.asciidoc[]
77 changes: 77 additions & 0 deletions docs/loading-json.asciidoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
[[loading-json]]
== Creating API objects from JSON data

A common workflow during application development with Elasticsearch is to use the Kibana Developer Console to interactively prepare and test queries, aggregations, index mappings and other complex API calls. This results in working JSON snippets that you may want to use in your application.

As translating these JSON snippets to Java code can be time-consuming and error-prone, most of the data classes in the {java-client} can be loaded from JSON text: object builders have `withJson()` methods that populate the builder from raw JSON. This also allows you to combine dynamically loaded JSON with programmatic construction of objects.

Under the hood, the `withJson()` methods call the object's deserializer. The JSON text's structure and value types therefore have to be correct for the target data structure. Using `withJson()` keeps the strong typing guarantees of the {java-client}.

[discrete]
=== Examples

[discrete]
==== Loading an index definition from a resource file

Consider a resource file `some-index.json` containing an index definition:

["source", "json"]
--------------------------------------------------
{
"mappings": {
"properties": {
"field1": { "type": "text" }
}
}
}
--------------------------------------------------

You can create an index from that definition as follows:

["source","java"]
--------------------------------------------------
include-tagged::{doc-tests}/LoadingJsonTest.java[load-index]
--------------------------------------------------
<1> open an input stream for the JSON resource file.
<2> populate the index creation request with the resource file contents.

[discrete]
==== Ingesting documents from JSON files

Similarly, you can read documents to be stored in {es} from data files:

["source","java"]
--------------------------------------------------
include-tagged::{doc-tests}/LoadingJsonTest.java[ingest-data]
--------------------------------------------------
<1> when calling `withJson()` on data structures that have generic type parameters, these generic types will be considered to be `JsonData`.

[discrete]
==== Creating a search request combining JSON and programmatic construction

You can combine `withJson()` with regular calls to setter methods. The example below loads the query part of a search request from a `String` and programmatically adds an aggregation.

["source","java"]
--------------------------------------------------
include-tagged::{doc-tests}/LoadingJsonTest.java[query]
--------------------------------------------------
<1> loads the query from the JSON string.
<2> adds the aggregation.
<3> since this is an aggregation we don't care about result documents and set their target class to `Void`, meaning they will just be ignored. Note that setting `size` to zero actually prevents any document from being returned.

[discrete]
==== Creating a search request from multiple JSON snippets

The `withJson()` methods are partial deserializers: the properties loaded from the JSON will set property values or replace the previous ones, but will not reset other properties not found in the JSON input. You can use this to combine multiple JSON snippets to build complex search requests. In the example below, we combine separate definitions of a query that selects some documents and an aggregation that is run on the results of this query.

["source","java"]
--------------------------------------------------
include-tagged::{doc-tests}/LoadingJsonTest.java[query-and-agg]
--------------------------------------------------
<1> set max number of returned document to 100 for queries.
<2> we do not want any matching document in aggregations.
<3> loads the query part of the request.
<4> loads the aggregation part of the request (overwrites `size` from the query).
<5> additional request properties set programmatically.

Notice that order matters when the JSON snippets have some common properties: just as when setting property values programmatically, the last value that is set for a property overwrites the previous one.
13 changes: 13 additions & 0 deletions java-client/src/main/java/co/elastic/clients/ApiClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

package co.elastic.clients;

import co.elastic.clients.json.JsonpMapper;
import co.elastic.clients.transport.TransportOptions;
import co.elastic.clients.transport.Transport;
import co.elastic.clients.json.JsonpDeserializer;
Expand Down Expand Up @@ -51,11 +52,23 @@ protected <V> JsonpDeserializer<V> getDeserializer(Class<V> clazz) {
*/
public abstract Self withTransportOptions(@Nullable TransportOptions transportOptions);

/**
* Get the transport used by this client to handle communication with the server.
*/
public T _transport() {
return this.transport;
}

public TransportOptions _transportOptions() {
return this.transportOptions;
}

/**
* Get the JSON mapper used to map API objects to/from JSON.
* <p>
* Shortcut for <code>_transport().jsonpMapper()</code>
*/
public JsonpMapper _jsonpMapper() {
return transport.jsonpMapper();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
import co.elastic.clients.json.ObjectDeserializer;
import co.elastic.clients.util.ApiTypeHelper;
import co.elastic.clients.util.ObjectBuilder;
import co.elastic.clients.util.ObjectBuilderBase;
import co.elastic.clients.util.WithJsonObjectBuilderBase;
import jakarta.json.stream.JsonGenerator;
import java.lang.Boolean;
import java.util.Objects;
Expand Down Expand Up @@ -83,7 +83,7 @@ protected void serializeInternal(JsonGenerator generator, JsonpMapper mapper) {

protected abstract static class AbstractBuilder<BuilderT extends AbstractBuilder<BuilderT>>
extends
ObjectBuilderBase {
WithJsonObjectBuilderBase<BuilderT> {
private Boolean acknowledged;

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
import co.elastic.clients.json.ObjectDeserializer;
import co.elastic.clients.util.ApiTypeHelper;
import co.elastic.clients.util.ObjectBuilder;
import co.elastic.clients.util.ObjectBuilderBase;
import co.elastic.clients.util.WithJsonObjectBuilderBase;
import jakarta.json.stream.JsonGenerator;
import java.lang.String;
import java.util.List;
Expand Down Expand Up @@ -162,7 +162,7 @@ protected void serializeInternal(JsonGenerator generator, JsonpMapper mapper) {

protected abstract static class AbstractBuilder<BuilderT extends AbstractBuilder<BuilderT>>
extends
ObjectBuilderBase {
WithJsonObjectBuilderBase<BuilderT> {
private Map<String, String> attributes;

private String host;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
import co.elastic.clients.json.ObjectDeserializer;
import co.elastic.clients.util.ApiTypeHelper;
import co.elastic.clients.util.ObjectBuilder;
import co.elastic.clients.util.ObjectBuilderBase;
import co.elastic.clients.util.WithJsonObjectBuilderBase;
import jakarta.json.stream.JsonGenerator;
import java.lang.Integer;
import java.lang.String;
Expand Down Expand Up @@ -143,7 +143,9 @@ protected void serializeInternal(JsonGenerator generator, JsonpMapper mapper) {
* Builder for {@link BulkIndexByScrollFailure}.
*/

public static class Builder extends ObjectBuilderBase implements ObjectBuilder<BulkIndexByScrollFailure> {
public static class Builder extends WithJsonObjectBuilderBase<Builder>
implements
ObjectBuilder<BulkIndexByScrollFailure> {
private ErrorCause cause;

private String id;
Expand Down Expand Up @@ -201,6 +203,11 @@ public final Builder type(String value) {
return this;
}

@Override
protected Builder self() {
return this;
}

/**
* Builds a {@link BulkIndexByScrollFailure}.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
import co.elastic.clients.json.ObjectDeserializer;
import co.elastic.clients.util.ApiTypeHelper;
import co.elastic.clients.util.ObjectBuilder;
import co.elastic.clients.util.ObjectBuilderBase;
import co.elastic.clients.util.WithJsonObjectBuilderBase;
import jakarta.json.stream.JsonGenerator;
import java.lang.Long;
import java.lang.String;
Expand Down Expand Up @@ -211,7 +211,7 @@ protected void serializeInternal(JsonGenerator generator, JsonpMapper mapper) {
* Builder for {@link BulkStats}.
*/

public static class Builder extends ObjectBuilderBase implements ObjectBuilder<BulkStats> {
public static class Builder extends WithJsonObjectBuilderBase<Builder> implements ObjectBuilder<BulkStats> {
private Long totalOperations;

@Nullable
Expand Down Expand Up @@ -306,6 +306,11 @@ public final Builder avgSizeInBytes(long value) {
return this;
}

@Override
protected Builder self() {
return this;
}

/**
* Builds a {@link BulkStats}.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
import co.elastic.clients.json.ObjectDeserializer;
import co.elastic.clients.util.ApiTypeHelper;
import co.elastic.clients.util.ObjectBuilder;
import co.elastic.clients.util.ObjectBuilderBase;
import co.elastic.clients.util.WithJsonObjectBuilderBase;
import jakarta.json.stream.JsonGenerator;
import java.lang.Integer;
import java.util.Objects;
Expand Down Expand Up @@ -115,7 +115,7 @@ protected void serializeInternal(JsonGenerator generator, JsonpMapper mapper) {
* Builder for {@link ClusterStatistics}.
*/

public static class Builder extends ObjectBuilderBase implements ObjectBuilder<ClusterStatistics> {
public static class Builder extends WithJsonObjectBuilderBase<Builder> implements ObjectBuilder<ClusterStatistics> {
private Integer skipped;

private Integer successful;
Expand Down Expand Up @@ -146,6 +146,11 @@ public final Builder total(int value) {
return this;
}

@Override
protected Builder self() {
return this;
}

/**
* Builds a {@link ClusterStatistics}.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
import co.elastic.clients.json.ObjectDeserializer;
import co.elastic.clients.util.ApiTypeHelper;
import co.elastic.clients.util.ObjectBuilder;
import co.elastic.clients.util.ObjectBuilderBase;
import co.elastic.clients.util.WithJsonObjectBuilderBase;
import jakarta.json.stream.JsonGenerator;
import java.lang.Long;
import java.lang.String;
Expand Down Expand Up @@ -131,7 +131,7 @@ protected void serializeInternal(JsonGenerator generator, JsonpMapper mapper) {
* Builder for {@link CompletionStats}.
*/

public static class Builder extends ObjectBuilderBase implements ObjectBuilder<CompletionStats> {
public static class Builder extends WithJsonObjectBuilderBase<Builder> implements ObjectBuilder<CompletionStats> {
private Long sizeInBytes;

@Nullable
Expand Down Expand Up @@ -185,6 +185,11 @@ public final Builder fields(String key, Function<FieldSizeUsage.Builder, ObjectB
return fields(key, fn.apply(new FieldSizeUsage.Builder()).build());
}

@Override
protected Builder self() {
return this;
}

/**
* Builds a {@link CompletionStats}.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
import co.elastic.clients.json.ObjectDeserializer;
import co.elastic.clients.util.ApiTypeHelper;
import co.elastic.clients.util.ObjectBuilder;
import co.elastic.clients.util.ObjectBuilderBase;
import co.elastic.clients.util.WithJsonObjectBuilderBase;
import jakarta.json.stream.JsonGenerator;
import java.lang.Double;
import java.util.Objects;
Expand Down Expand Up @@ -128,7 +128,7 @@ protected void serializeInternal(JsonGenerator generator, JsonpMapper mapper) {
* Builder for {@link CoordsGeoBounds}.
*/

public static class Builder extends ObjectBuilderBase implements ObjectBuilder<CoordsGeoBounds> {
public static class Builder extends WithJsonObjectBuilderBase<Builder> implements ObjectBuilder<CoordsGeoBounds> {
private Double top;

private Double bottom;
Expand Down Expand Up @@ -169,6 +169,11 @@ public final Builder right(double value) {
return this;
}

@Override
protected Builder self() {
return this;
}

/**
* Builds a {@link CoordsGeoBounds}.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
import co.elastic.clients.json.ObjectDeserializer;
import co.elastic.clients.util.ApiTypeHelper;
import co.elastic.clients.util.ObjectBuilder;
import co.elastic.clients.util.ObjectBuilderBase;
import co.elastic.clients.util.WithJsonObjectBuilderBase;
import jakarta.json.stream.JsonGenerator;
import java.lang.Long;
import java.util.Objects;
Expand Down Expand Up @@ -108,7 +108,7 @@ protected void serializeInternal(JsonGenerator generator, JsonpMapper mapper) {
* Builder for {@link DocStats}.
*/

public static class Builder extends ObjectBuilderBase implements ObjectBuilder<DocStats> {
public static class Builder extends WithJsonObjectBuilderBase<Builder> implements ObjectBuilder<DocStats> {
private Long count;

@Nullable
Expand All @@ -130,6 +130,11 @@ public final Builder deleted(@Nullable Long value) {
return this;
}

@Override
protected Builder self() {
return this;
}

/**
* Builds a {@link DocStats}.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
import co.elastic.clients.util.ApiTypeHelper;
import co.elastic.clients.util.DateTime;
import co.elastic.clients.util.ObjectBuilder;
import co.elastic.clients.util.ObjectBuilderBase;
import co.elastic.clients.util.WithJsonObjectBuilderBase;
import jakarta.json.stream.JsonGenerator;
import java.lang.Boolean;
import java.lang.String;
Expand Down Expand Up @@ -197,7 +197,9 @@ protected void serializeInternal(JsonGenerator generator, JsonpMapper mapper) {
* Builder for {@link ElasticsearchVersionInfo}.
*/

public static class Builder extends ObjectBuilderBase implements ObjectBuilder<ElasticsearchVersionInfo> {
public static class Builder extends WithJsonObjectBuilderBase<Builder>
implements
ObjectBuilder<ElasticsearchVersionInfo> {
private DateTime buildDate;

private String buildFlavor;
Expand Down Expand Up @@ -288,6 +290,11 @@ public final Builder number(String value) {
return this;
}

@Override
protected Builder self() {
return this;
}

/**
* Builds a {@link ElasticsearchVersionInfo}.
*
Expand Down
Loading