DEV Community

Committed Software
Committed Software

Posted on • Originally published at committed.software on

Debugging Elasticsearch Queries in Java: how to convert queries to JSON

Code Data Programming Code Computer Programming cc zero

Elasticsearch has excellent documentation with detailed descriptions and plenty of examples. The Elasticsearch Java API has handy builder classes accessible from org.elasticsearch.index.query.QueryBuilders to craft queries and aggregations in an intuitive and fluent way that is idiomatic to Java.

Unintuitively, however, QueryBuilder and AggregationBuilder subclasses do not implement toString, making it harder to debug and analyze these Java calls than you would expect, as it is not always clear how they compare to the Elasticsearch-native JSON format used extensively in Elasticsearch’s documentation. This issue is compounded further when the construction of queries is out of your control!

One way we could view our queries in JSON format is to enable elasticseach’s Slow Log, but there is a simpler way, using the Java Elasticsearch API to achieve what we want:

import java.io.IOException;
import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.json.JsonXContent;

...

public static void toJSON(ToXContent queryBuilder) {
  try {
    XContentBuilder builder =
        queryBuilder.toXContent(JsonXContent.contentBuilder(), ToXContent.EMPTY_PARAMS);
    log.info(builder.string());
  } catch (IOException e) {
    log.error("Failed to log elasticsearch query", e);
  }
}

...

This can be used for classes implementing either QueryBuilder or AggregationBuilder, as both of these extend the ToXContent interface.

We can use the same approach when using Spring Data Elasticsearch by calling NativeSearchQueryBuilder.getQuery(), NativeSearchQueryBuilder.getFilter() or NativeSearchQueryBuilder.getAggregations() and passing the resulting objects using the same approach.

Now we can see the exact query that will be sent to Elasticsearch:

{ "term" : { "user" : "Kimchy" } }

If you are using Kibana to view your indices, try copying & pasting your query across on the Discover page for further analysis.

Top comments (0)