You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/reference/dsl_how_to_guides.md
+121Lines changed: 121 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1425,6 +1425,127 @@ print(response.took)
1425
1425
If you want to inspect the contents of the `response` objects, just use its `to_dict` method to get access to the raw data for pretty printing.
1426
1426
1427
1427
1428
+
## ES|QL Queries
1429
+
1430
+
When working with`Document` classes, you can use the ES|QL query language to retrieve documents. For this you can use the `esql_from()`and`esql_execute()` methods available to all sub-classes of `Document`.
1431
+
1432
+
Consider the following `Employee` document definition:
1433
+
1434
+
```python
1435
+
from elasticsearch.dsl import Document, InnerDoc, M
1436
+
1437
+
class Address(InnerDoc):
1438
+
address: M[str]
1439
+
city: M[str]
1440
+
zip_code: M[str]
1441
+
1442
+
class Employee(Document):
1443
+
emp_no: M[int]
1444
+
first_name: M[str]
1445
+
last_name: M[str]
1446
+
height: M[float]
1447
+
still_hired: M[bool]
1448
+
address: M[Address]
1449
+
1450
+
class Index:
1451
+
name='employees'
1452
+
```
1453
+
1454
+
The `esql_from()` method creates a base ES|QL query for the index associated with the document class. The following example creates a base query for the `Employee`class:
1455
+
1456
+
```python
1457
+
query= Employee.esql_from()
1458
+
```
1459
+
1460
+
This query includes a `FROM` command with the index name, and a `KEEP` command that retrieves all the document attributes.
1461
+
1462
+
To execute this query and receive the results, you can pass the query to the `esql_execute()` method:
1463
+
1464
+
```python
1465
+
for emp in Employee.esql_execute(query):
1466
+
print(f"{emp.name} from {emp.address.city} is {emp.height:.2f}m tall")
1467
+
```
1468
+
1469
+
In this example, the `esql_execute()`class method runs the query and returns all the documents in the index, up to the maximum of 1000 results allowed by ES|QL. Here is a possible output from this example:
1470
+
1471
+
```
1472
+
Kevin Macias from North Robert is1.60m tall
1473
+
Drew Harris from Boltonshire is1.68m tall
1474
+
Julie Williams from Maddoxshire is1.99m tall
1475
+
Christopher Jones from Stevenbury is1.98m tall
1476
+
Anthony Lopez from Port Sarahtown is2.42m tall
1477
+
Tricia Stone from North Sueshire is2.39m tall
1478
+
Katherine Ramirez from Kimberlyton is1.83m tall
1479
+
...
1480
+
```
1481
+
1482
+
To search for specific documents you can extend the base query with additional ES|QL commands that narrow the search criteria. The next example searches for documents that include only employees that are taller than 2 meters, sorted by their last name. It also limits the results to 4 people:
1483
+
1484
+
```python
1485
+
query= (
1486
+
Employee.esql_from()
1487
+
.where(Employee.height >2)
1488
+
.sort(Employee.last_name)
1489
+
.limit(4)
1490
+
)
1491
+
```
1492
+
1493
+
When running this query with the same for-loop shown above, possible results would be:
1494
+
1495
+
```
1496
+
Michael Adkins from North Stacey is2.48m tall
1497
+
Kimberly Allen from Toddside is2.24m tall
1498
+
Crystal Austin from East Michaelchester is2.30m tall
1499
+
Rebecca Berger from Lake Adrianside is2.40m tall
1500
+
```
1501
+
1502
+
### Additional fields
1503
+
1504
+
ES|QL provides a few ways to add new fields to a query, for example through the `EVAL` command. The following example shows a query that adds an evaluated field:
In this example we are adding the height in centimeters to the query, calculated from the `height` document field, which isin meters. The `height_cm` calculated field is available to use in other query clauses, andin particular is referenced in`where()`in this example. Note how the new field is given as`E("height_cm")`in this clause. The `E()` wrapper tells the query builder that the argument is an ES|QL field name andnot a string literal. This is done automatically for document fields that are given asclass attributes, such as`Employee.height`in the `eval()`. The `E()` wrapper is only needed for fields that are notin the document.
1519
+
1520
+
By default, the `esql_execute()` method returns only document instances. To receive any additional fields that are not part of the document in the query results, the `return_additional=True` argument can be passed to it, and then the results are returned as tuples with the document as first element, and a dictionary with the additional fields as second element:
1521
+
1522
+
```python
1523
+
for emp, additional in Employee.esql_execute(query, return_additional=True):
1524
+
print(emp.name, additional)
1525
+
```
1526
+
1527
+
Example output from the query given above:
1528
+
1529
+
```
1530
+
Michael Adkins {'height_cm': 248.0}
1531
+
Kimberly Allen {'height_cm': 224.0}
1532
+
Crystal Austin {'height_cm': 230.0}
1533
+
Rebecca Berger {'height_cm': 240.0}
1534
+
Katherine Blake {'height_cm': 214.0}
1535
+
Edward Butler {'height_cm': 246.0}
1536
+
Steven Carlson {'height_cm': 242.0}
1537
+
Mark Carter {'height_cm': 240.0}
1538
+
Joseph Castillo {'height_cm': 229.0}
1539
+
Alexander Cohen {'height_cm': 245.0}
1540
+
```
1541
+
1542
+
### Missing fields
1543
+
1544
+
The base query returned by the `esql_from()` method includes a `KEEP` command with the complete list of fields that are part of the document. If any subsequent clauses added to the query remove fields that are part of the document, then the `esql_execute()` method will raise an exception, because it will not be able construct complete document instances to returnas results.
1545
+
1546
+
To prevent errors, it is recommended that the `keep()`and`drop()` clauses are not used when working with`Document` instances.
1547
+
1548
+
If a query has missing fields, it can be forced to execute without errors by passing the `ignore_missing_fields=True` argument to `esql_execute()`. When this option is used, returned documents will have any missing fields set to `None`.
1428
1549
1429
1550
## Using asyncio with Elasticsearch Python DSL [asyncio]
As you can see, the `Update By Query` object provides many of the savings offered by the `Search` object, and additionally allows one to update the results of the search based on a script assigned in the same manner.
217
217
218
218
219
+
## ES|QL Queries
220
+
221
+
The DSL module features an integration with the ES|QL query builder, consisting of two methods available in all `Document` sub-classes: `esql_from()` and `esql_execute()`. Using the `Article` document from above, we can search for up to ten articles that include `"world"` in their titles with the following ES|QL query:
Review the [ES|QL Query Builder section](esql-query-builder.md) to learn more about building ES|QL queries in Python.
232
+
219
233
## Migration from the standard client [_migration_from_the_standard_client]
220
234
221
235
You don’t have to port your entire application to get the benefits of the DSL module, you can start gradually by creating a `Search` object from your existing `dict`, modifying it using the API and serializing it back to a `dict`:
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:
Here the part of the query in which the untrusted data needs to be inserted is replaced with a parameter, which in ES|QL is defined by the question mark. When using Python expressions, the parameter must be given as `E("?")` so that it is treated as an expression and not as a literal string.
0 commit comments