Indexing single documents

edit

The Java API Client offers several ways to index data: you can provide application objects that will be automatically mapped to JSON, or you can provide raw JSON data. Using application objects is more suited to applications with a well-defined domain model, whereas raw JSON is more suited to logging use cases with semi-structured data.

In the examples below we use a Product domain object that has sku, name and price properties.

See the Elasticsearch API documentation for a full explanation of index requests.

Using the fluent DSL

edit

The most direct way to build requests is using the fluent DSL. In the example below we index a product description in the products index, using the product’s SKU as the document identifier in the index. The product object will be mapped to JSON using the object mapper configured on the Elasticsearch client.

Product product = new Product("bk-1", "City bike", 123.0);

IndexResponse response = esClient.index(i -> i
    .index("products")
    .id(product.getSku())
    .document(product)
);

logger.info("Indexed with version " + response.version());

You can also assign objects created with the DSL to variables. Java API Client classes have a static of() method for this, that creates an object with the DSL syntax.

Product product = new Product("bk-1", "City bike", 123.0);

IndexRequest<Product> request = IndexRequest.of(i -> i
    .index("products")
    .id(product.getSku())
    .document(product)
);

IndexResponse response = esClient.index(request);

logger.info("Indexed with version " + response.version());

Using classic builders

edit

If you’re more used to the classic builder pattern, it is also available. Builder objects are used under the hood by the fluent DSL syntax.

Product product = new Product("bk-1", "City bike", 123.0);

IndexRequest.Builder<Product> indexReqBuilder = new IndexRequest.Builder<>();
indexReqBuilder.index("product");
indexReqBuilder.id(product.getSku());
indexReqBuilder.document(product);

IndexResponse response = esClient.index(indexReqBuilder.build());

logger.info("Indexed with version " + response.version());

Using the asynchronous client

edit

The examples above used the synchronous Elasticsearch client. All Elasticsearch APIs are also available in the asynchronous client, using the same request and response types. See also Blocking and asynchronous clients for additional details.

ElasticsearchAsyncClient esAsyncClient = new ElasticsearchAsyncClient(transport);

Product product = new Product("bk-1", "City bike", 123.0);

esAsyncClient.index(i -> i
    .index("products")
    .id(product.getSku())
    .document(product)
).whenComplete((response, exception) -> {
    if (exception != null) {
        logger.error("Failed to index", exception);
    } else {
        logger.info("Indexed with version " + response.version());
    }
});

Using raw JSON data

edit

When the data you want to index comes from external sources, having to create domain objects may be cumbersome or outright impossible with semi-structured data.

You can index data from an arbitrary source using withJson(). Using this method will read the source and use it for the index request’s document property. See Creating API objects from JSON data for additional details.

Reader input = new StringReader(
    "{'@timestamp': '2022-04-08T13:55:32Z', 'level': 'warn', 'message': 'Some log message'}"
    .replace('\'', '"'));

IndexRequest<JsonData> request = IndexRequest.of(i -> i
    .index("logs")
    .withJson(input)
);

IndexResponse response = esClient.index(request);

logger.info("Indexed with version " + response.version());

The source code for the examples above can be found in the Java API Client tests.