The Elasticsearch API has a lot of variant types: queries, aggregations, field mappings, analyzers, and so on. Finding the correct class name in such large collections can be challenging.
The Java API Client builders make this easy: the builders for variant types, such as
Query, have methods for each of the available implementations. We’ve seen this
in action above with
intervals (a kind of query) and
anyOf (various kinds of intervals).
This is because variant objects in the Java API Client are implementations of a
“tagged union”: they contain the identifier (or tag) of the variant they hold
and the value for that variant. For example, a
Query object can contain an
IntervalsQuery with tag
TermQuery with tag
term, and so on.
This approach allows writing fluent code where you can let the IDE completion
features guide you to build and navigate complex nested structures:
Variant builders have setter methods for every available implementation. They use the same conventions as regular properties and accept both a builder lambda expression and a ready-made object of the actual type of the variant. Here’s an example to build a term query:
Build the terms query with a builder lambda expression.
Variant objects have getter methods for every available implementation. These
methods check that the object actually holds a variant of that kind and return
the value downcasted to the correct type. They throw an
otherwise. This approach allows writing fluent code to traverse variants.
Variant objects also provide information on the variant kind they currently hold:
ismethods for each of the variant kinds:
with a nested
Kindenumeration that defines all variant kinds.
This information can then be used to navigate down into specific variants after checking their actual kind:
Test if the variant is of a specific kind.
Test a larger set of variant kinds.
Get the kind and value held by the variant object.
The source code for the examples above can be found in the Java API Client tests.