|
| 1 | +[[esql]] |
| 2 | +=== ES|QL in the Java client |
| 3 | + |
| 4 | +This page helps you understand and use {ref}/esql.html[ES|QL] in the |
| 5 | +Java client. |
| 6 | + |
| 7 | +There are two ways to use ES|QL in the {java-client}: |
| 8 | + |
| 9 | +* Use the Elasticsearch {es-docs}/esql-apis.html[ES|QL API] directly: This |
| 10 | +is the most flexible approach, but it's also the most complex because you must handle |
| 11 | +results in their raw form. You can choose the precise format of results, |
| 12 | +such as JSON, CSV, or text. |
| 13 | +* Use ES|QL mapping helpers: These mappers take care of parsing the raw |
| 14 | +response into something readily usable by the application. Several mappers are |
| 15 | +available for different use cases, such as object mapping, cursor |
| 16 | +traversal of results, and dataframes. You can also define your own mapper for specific |
| 17 | +use cases. |
| 18 | + |
| 19 | + |
| 20 | + |
| 21 | +[discrete] |
| 22 | +[[esql-how-to]] |
| 23 | +==== How to use the ES|QL API |
| 24 | + |
| 25 | +The {es-docs}/esql-query-api.html[ES|QL query API] allows you to specify how |
| 26 | +results should be returned. You can choose a |
| 27 | +{es-docs}/esql-rest.html#esql-rest-format[response format] such as CSV, text, or |
| 28 | +JSON, then fine-tune it with parameters like column separators |
| 29 | +and locale. |
| 30 | + |
| 31 | +Because the response varies widely depending on the format, the |
| 32 | +{java-client} has a BinaryData object you can use according to the |
| 33 | +format specified in the request. |
| 34 | + |
| 35 | +The following example gets ES|QL results as CSV and parses them: |
| 36 | + |
| 37 | +[source,java] |
| 38 | +------------------------------------ |
| 39 | +String queryAuthor = |
| 40 | + """ |
| 41 | + from books |
| 42 | + | where author == "Isaac Asimov" |
| 43 | + | sort year desc |
| 44 | + | limit 10 |
| 45 | + """; |
| 46 | +
|
| 47 | +BinaryResponse response = client.esql().query(q -> q |
| 48 | + .format("csv") |
| 49 | + .delimiter(",") |
| 50 | + .query(queryAuthor)); |
| 51 | +
|
| 52 | +String result = new BufferedReader(new InputStreamReader(response.content())) |
| 53 | + .lines().collect(Collectors.joining("\n")); |
| 54 | +------------------------------------ |
| 55 | + |
| 56 | + |
| 57 | +[discrete] |
| 58 | +[[esql-consume-results]] |
| 59 | +==== Consume ES|QL results |
| 60 | + |
| 61 | +The previous example showed that although the raw ES|QL API offers maximum |
| 62 | +flexibility, additional work is required in order to make use of the |
| 63 | +result data. |
| 64 | + |
| 65 | +To simplify things, try working with these three main representations of ES|QL |
| 66 | +results (each with its own mapping helper): |
| 67 | + |
| 68 | +* **Objects**, where each row in the results is mapped to an object from your |
| 69 | +application domain. This is similar to what ORMs (object relational mappers) |
| 70 | +commonly do. |
| 71 | ++ |
| 72 | +-- |
| 73 | + |
| 74 | +[source,java] |
| 75 | +------------------------------------ |
| 76 | +List<Book> queryRes = (List<Book>) client.esql().query(ObjectsEsqlAdapter.of(Book.class), queryAuthor); |
| 77 | +
|
| 78 | +------------------------------------ |
| 79 | +-- |
| 80 | +* **Cursors**, where you scan the results row by row and access the data using |
| 81 | +column names. This is similar to database access libraries. |
| 82 | ++ |
| 83 | +-- |
| 84 | +[source,java] |
| 85 | +------------------------------------ |
| 86 | +ResultSet resultSet = client.esql().query(ResultSetEsqlAdapter.INSTANCE, queryAuthor); |
| 87 | +------------------------------------ |
| 88 | +-- |
| 89 | + |
| 90 | + |
| 91 | +[discrete] |
| 92 | +[[esql-custom-mapping]] |
| 93 | +==== Define your own mapping |
| 94 | + |
| 95 | +Although the mappers provided by the {java-client} cover many use cases, your |
| 96 | +application might require a custom mapping. |
| 97 | +You can write your own mapper and use it in a similar way as the |
| 98 | +built-in ones. |
| 99 | + |
| 100 | +Note that mappers are meant to provide a more usable representation of ES|QL |
| 101 | +results—not to process the result data. Data processing should be based on |
| 102 | +the output of a result mapper. |
| 103 | + |
| 104 | +Here's an example mapper that returns a simple column-oriented |
| 105 | +representation of the data: |
| 106 | + |
| 107 | +[source,java] |
| 108 | +------------------------------------ |
| 109 | +public class CustomStringAdapter extends EsqlAdapterBase<String> { |
| 110 | +
|
| 111 | + public static final CustomStringAdapter INSTANCE = new CustomStringAdapter(); |
| 112 | +
|
| 113 | + @Override |
| 114 | + public String format() { |
| 115 | + return "json"; |
| 116 | + } |
| 117 | +
|
| 118 | + @Override |
| 119 | + public boolean columnar() { |
| 120 | + return true; |
| 121 | + } |
| 122 | +
|
| 123 | + @Override |
| 124 | + public String deserialize(ApiClient<ElasticsearchTransport, ?> client, QueryRequest request, |
| 125 | + BinaryResponse response) |
| 126 | + throws IOException { |
| 127 | + return new BufferedReader(new InputStreamReader(response.content())) |
| 128 | + .lines().collect(Collectors.joining("\n")); |
| 129 | + } |
| 130 | +} |
| 131 | +------------------------------------ |
0 commit comments