Skip to content

Commit 66dab93

Browse files
md to asciidoc docs translation
1 parent 1ee529d commit 66dab93

File tree

2 files changed

+259
-0
lines changed

2 files changed

+259
-0
lines changed
Lines changed: 255 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,255 @@
1+
[[esql-query-builder]]
2+
== ES|QL Query Builder
3+
4+
::::{warning}
5+
This functionality is in technical preview and may be changed or removed in a future release. Elastic will work to fix any issues, but features in technical preview are not subject to the support SLA of official GA features.
6+
::::
7+
8+
The ES|QL Query Builder allows you to construct ES|QL queries using Python syntax. Consider the following example:
9+
10+
[source, python]
11+
----------------------------
12+
>>> from elasticsearch.esql import ESQL
13+
>>> query = (
14+
ESQL.from_("employees")
15+
.sort("emp_no")
16+
.keep("first_name", "last_name", "height")
17+
.eval(height_feet="height * 3.281", height_cm="height * 100")
18+
.limit(3)
19+
)
20+
----------------------------
21+
22+
You can then see the assembled ES|QL query by printing the resulting query object:
23+
24+
[source, python]
25+
----------------------------
26+
>>> query
27+
FROM employees
28+
| SORT emp_no
29+
| KEEP first_name, last_name, height
30+
| EVAL height_feet = height * 3.281, height_cm = height * 100
31+
| LIMIT 3
32+
----------------------------
33+
34+
To execute this query, you can cast it to a string and pass the string to the `client.esql.query()` endpoint:
35+
36+
[source, python]
37+
----------------------------
38+
>>> from elasticsearch import Elasticsearch
39+
>>> client = Elasticsearch(hosts=[os.environ['ELASTICSEARCH_URL']])
40+
>>> response = client.esql.query(query=str(query))
41+
----------------------------
42+
43+
The response body contains a `columns` attribute with the list of columns included in the results, and a `values` attribute with the list of results for the query, each given as a list of column values. Here is a possible response body returned by the example query given above:
44+
45+
[source, python]
46+
----------------------------
47+
>>> from pprint import pprint
48+
>>> pprint(response.body)
49+
{'columns': [{'name': 'first_name', 'type': 'text'},
50+
{'name': 'last_name', 'type': 'text'},
51+
{'name': 'height', 'type': 'double'},
52+
{'name': 'height_feet', 'type': 'double'},
53+
{'name': 'height_cm', 'type': 'double'}],
54+
'is_partial': False,
55+
'took': 11,
56+
'values': [['Adrian', 'Wells', 2.424, 7.953144, 242.4],
57+
['Aaron', 'Gonzalez', 1.584, 5.1971, 158.4],
58+
['Miranda', 'Kramer', 1.55, 5.08555, 155]]}
59+
----------------------------
60+
61+
=== Creating an ES|QL query
62+
63+
To construct an ES|QL query you start from one of the ES|QL source commands:
64+
65+
==== `ESQL.from_`
66+
67+
The `FROM` command selects the indices, data streams or aliases to be queried.
68+
69+
Examples:
70+
71+
[source, python]
72+
----------------------------
73+
from elasticsearch.esql import ESQL
74+
75+
# FROM employees
76+
query1 = ESQL.from_("employees")
77+
78+
# FROM <logs-{now/d}>
79+
query2 = ESQL.from_("<logs-{now/d}>")
80+
81+
# FROM employees-00001, other-employees-*
82+
query3 = ESQL.from_("employees-00001", "other-employees-*")
83+
84+
# FROM cluster_one:employees-00001, cluster_two:other-employees-*
85+
query4 = ESQL.from_("cluster_one:employees-00001", "cluster_two:other-employees-*")
86+
87+
# FROM employees METADATA _id
88+
query5 = ESQL.from_("employees").metadata("_id")
89+
----------------------------
90+
91+
Note how in the last example the optional `METADATA` clause of the `FROM` command is added as a chained method.
92+
93+
==== `ESQL.row`
94+
95+
The `ROW` command produces a row with one or more columns, with the values that you specify.
96+
97+
Examples:
98+
99+
[source, python]
100+
----------------------------
101+
from elasticsearch.esql import ESQL, functions
102+
103+
# ROW a = 1, b = "two", c = null
104+
query1 = ESQL.row(a=1, b="two", c=None)
105+
106+
# ROW a = [1, 2]
107+
query2 = ESQL.row(a=[1, 2])
108+
109+
# ROW a = ROUND(1.23, 0)
110+
query3 = ESQL.row(a=functions.round(1.23, 0))
111+
----------------------------
112+
113+
==== `ESQL.show`
114+
115+
The `SHOW` command returns information about the deployment and its capabilities.
116+
117+
Example:
118+
119+
[source, python]
120+
----------------------------
121+
from elasticsearch.esql import ESQL
122+
123+
# SHOW INFO
124+
query = ESQL.show("INFO")
125+
----------------------------
126+
127+
=== Adding processing commands
128+
129+
Once you have a query object, you can add one or more processing commands to it. The following
130+
example shows how to create a query that uses the `WHERE` and `LIMIT` commands to filter the
131+
results:
132+
133+
[source, python]
134+
----------------------------
135+
from elasticsearch.esql import ESQL
136+
137+
# FROM employees
138+
# | WHERE still_hired == true
139+
# | LIMIT 10
140+
query = ESQL.from_("employees").where("still_hired == true").limit(10)
141+
----------------------------
142+
143+
For a complete list of available commands, review the methods of the https://elasticsearch-py.readthedocs.io/en/stable/esql.html[`ESQLBase` class] in the Elasticsearch Python API documentation.
144+
145+
=== Creating ES|QL Expressions and Conditions
146+
147+
The ES|QL query builder for Python provides two ways to create expressions and conditions in ES|QL queries.
148+
149+
The simplest option is to provide all ES|QL expressions and conditionals as strings. The following example uses this approach to add two calculated columns to the results using the `EVAL` command:
150+
151+
[source, python]
152+
----------------------------
153+
from elasticsearch.esql import ESQL
154+
155+
# FROM employees
156+
# | SORT emp_no
157+
# | KEEP first_name, last_name, height
158+
# | EVAL height_feet = height * 3.281, height_cm = height * 100
159+
query = (
160+
ESQL.from_("employees")
161+
.sort("emp_no")
162+
.keep("first_name", "last_name", "height")
163+
.eval(height_feet="height * 3.281", height_cm="height * 100")
164+
)
165+
----------------------------
166+
167+
A more advanced alternative is to replace the strings with Python expressions, which are automatically translated to ES|QL when the query object is rendered to a string. The following example is functionally equivalent to the one above:
168+
169+
[source, python]
170+
----------------------------
171+
from elasticsearch.esql import ESQL, E
172+
173+
# FROM employees
174+
# | SORT emp_no
175+
# | KEEP first_name, last_name, height
176+
# | EVAL height_feet = height * 3.281, height_cm = height * 100
177+
query = (
178+
ESQL.from_("employees")
179+
.sort("emp_no")
180+
.keep("first_name", "last_name", "height")
181+
.eval(height_feet=E("height") * 3.281, height_cm=E("height") * 100)
182+
)
183+
----------------------------
184+
185+
Here the `E()` helper function is used as a wrapper to the column name that initiates an ES|QL expression. The `E()` function transforms the given column into an ES|QL expression that can be modified with Python operators.
186+
187+
Here is a second example, which uses a conditional expression in the `WHERE` command:
188+
189+
[source, python]
190+
----------------------------
191+
from elasticsearch.esql import ESQL
192+
193+
# FROM employees
194+
# | KEEP first_name, last_name, height
195+
# | WHERE first_name == "Larry"
196+
query = (
197+
ESQL.from_("employees")
198+
.keep("first_name", "last_name", "height")
199+
.where('first_name == "Larry"')
200+
)
201+
----------------------------
202+
203+
Using Python syntax, the condition can be rewritten as follows:
204+
205+
[source, python]
206+
----------------------------
207+
from elasticsearch.esql import ESQL, E
208+
209+
# FROM employees
210+
# | KEEP first_name, last_name, height
211+
# | WHERE first_name == "Larry"
212+
query = (
213+
ESQL.from_("employees")
214+
.keep("first_name", "last_name", "height")
215+
.where(E("first_name") == "Larry")
216+
)
217+
----------------------------
218+
219+
=== Using ES|QL functions
220+
221+
The ES|QL language includes a rich set of functions that can be used in expressions and conditionals. These can be included in expressions given as strings, as shown in the example below:
222+
223+
[source, python]
224+
----------------------------
225+
from elasticsearch.esql import ESQL
226+
227+
# FROM employees
228+
# | KEEP first_name, last_name, height
229+
# | WHERE LENGTH(first_name) < 4"
230+
query = (
231+
ESQL.from_("employees")
232+
.keep("first_name", "last_name", "height")
233+
.where("LENGTH(first_name) < 4")
234+
)
235+
----------------------------
236+
237+
All available ES|QL functions have Python wrappers in the `elasticsearch.esql.functions` module, which can be used when building expressions using Python syntax. Below is the example above coded using Python syntax:
238+
239+
[source, python]
240+
----------------------------
241+
from elasticsearch.esql import ESQL, functions
242+
243+
# FROM employees
244+
# | KEEP first_name, last_name, height
245+
# | WHERE LENGTH(first_name) < 4"
246+
query = (
247+
ESQL.from_("employees")
248+
.keep("first_name", "last_name", "height")
249+
.where(functions.length(E("first_name")) < 4)
250+
)
251+
----------------------------
252+
253+
Note that arguments passed to functions are assumed to be literals. When passing field names, it is necessary to wrap them with the `E()` helper function so that they are interpreted correctly.
254+
255+
You can find the complete list of available functions in the Python client's https://elasticsearch-py.readthedocs.io/en/stable/esql.html#module-elasticsearch.esql.functions[ES|QL API reference documentation].

docs/guide/index.asciidoc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ include::connecting.asciidoc[]
1616

1717
include::configuration.asciidoc[]
1818

19+
include::esql-query-builder.asciidoc[]
20+
21+
include::async.asciidoc[]
22+
1923
include::migration.asciidoc[]
2024

2125
include::integrations.asciidoc[]

0 commit comments

Comments
 (0)