elasticsearch9 9.0.3__py3-none-any.whl → 9.0.5__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- elasticsearch9/_async/client/__init__.py +19 -6
- elasticsearch9/_async/client/cat.py +610 -26
- elasticsearch9/_async/client/esql.py +16 -6
- elasticsearch9/_async/client/indices.py +2 -2
- elasticsearch9/_async/client/logstash.py +3 -1
- elasticsearch9/_async/client/sql.py +1 -1
- elasticsearch9/_async/client/transform.py +60 -0
- elasticsearch9/_sync/client/__init__.py +19 -6
- elasticsearch9/_sync/client/cat.py +610 -26
- elasticsearch9/_sync/client/esql.py +16 -6
- elasticsearch9/_sync/client/indices.py +2 -2
- elasticsearch9/_sync/client/logstash.py +3 -1
- elasticsearch9/_sync/client/sql.py +1 -1
- elasticsearch9/_sync/client/transform.py +60 -0
- elasticsearch9/_version.py +1 -1
- elasticsearch9/dsl/__init__.py +28 -0
- elasticsearch9/dsl/_async/document.py +84 -0
- elasticsearch9/dsl/_sync/document.py +84 -0
- elasticsearch9/dsl/aggs.py +97 -0
- elasticsearch9/dsl/document_base.py +43 -0
- elasticsearch9/dsl/field.py +27 -10
- elasticsearch9/dsl/response/__init__.py +3 -0
- elasticsearch9/dsl/response/aggs.py +1 -1
- elasticsearch9/dsl/types.py +203 -13
- elasticsearch9/dsl/utils.py +1 -1
- elasticsearch9/esql/__init__.py +2 -1
- elasticsearch9/esql/esql.py +85 -34
- elasticsearch9/esql/functions.py +37 -25
- {elasticsearch9-9.0.3.dist-info → elasticsearch9-9.0.5.dist-info}/METADATA +1 -3
- {elasticsearch9-9.0.3.dist-info → elasticsearch9-9.0.5.dist-info}/RECORD +33 -33
- {elasticsearch9-9.0.3.dist-info → elasticsearch9-9.0.5.dist-info}/WHEEL +1 -1
- {elasticsearch9-9.0.3.dist-info → elasticsearch9-9.0.5.dist-info}/licenses/LICENSE +0 -0
- {elasticsearch9-9.0.3.dist-info → elasticsearch9-9.0.5.dist-info}/licenses/NOTICE +0 -0
|
@@ -22,6 +22,9 @@ from elastic_transport import ObjectApiResponse
|
|
|
22
22
|
from ._base import NamespacedClient
|
|
23
23
|
from .utils import SKIP_IN_PATH, _quote, _rewrite_parameters
|
|
24
24
|
|
|
25
|
+
if t.TYPE_CHECKING:
|
|
26
|
+
from elasticsearch.esql import ESQLBase
|
|
27
|
+
|
|
25
28
|
|
|
26
29
|
class EsqlClient(NamespacedClient):
|
|
27
30
|
|
|
@@ -44,7 +47,7 @@ class EsqlClient(NamespacedClient):
|
|
|
44
47
|
def async_query(
|
|
45
48
|
self,
|
|
46
49
|
*,
|
|
47
|
-
query: t.Optional[str] = None,
|
|
50
|
+
query: t.Optional[t.Union[str, "ESQLBase"]] = None,
|
|
48
51
|
columnar: t.Optional[bool] = None,
|
|
49
52
|
delimiter: t.Optional[str] = None,
|
|
50
53
|
drop_null_columns: t.Optional[bool] = None,
|
|
@@ -99,7 +102,12 @@ class EsqlClient(NamespacedClient):
|
|
|
99
102
|
which has the name of all the columns.
|
|
100
103
|
:param filter: Specify a Query DSL query in the filter parameter to filter the
|
|
101
104
|
set of documents that an ES|QL query runs on.
|
|
102
|
-
:param format: A short version of the Accept header,
|
|
105
|
+
:param format: A short version of the Accept header, e.g. json, yaml. `csv`,
|
|
106
|
+
`tsv`, and `txt` formats will return results in a tabular format, excluding
|
|
107
|
+
other metadata fields from the response. For async requests, nothing will
|
|
108
|
+
be returned if the async query doesn't finish within the timeout. The query
|
|
109
|
+
ID and running status are available in the `X-Elasticsearch-Async-Id` and
|
|
110
|
+
`X-Elasticsearch-Async-Is-Running` HTTP headers of the response, respectively.
|
|
103
111
|
:param include_ccs_metadata: When set to `true` and performing a cross-cluster
|
|
104
112
|
query, the response will include an extra `_clusters` object with information
|
|
105
113
|
about the clusters that participated in the search along with info such as
|
|
@@ -151,7 +159,7 @@ class EsqlClient(NamespacedClient):
|
|
|
151
159
|
__query["pretty"] = pretty
|
|
152
160
|
if not __body:
|
|
153
161
|
if query is not None:
|
|
154
|
-
__body["query"] = query
|
|
162
|
+
__body["query"] = str(query)
|
|
155
163
|
if columnar is not None:
|
|
156
164
|
__body["columnar"] = columnar
|
|
157
165
|
if filter is not None:
|
|
@@ -389,7 +397,7 @@ class EsqlClient(NamespacedClient):
|
|
|
389
397
|
def query(
|
|
390
398
|
self,
|
|
391
399
|
*,
|
|
392
|
-
query: t.Optional[str] = None,
|
|
400
|
+
query: t.Optional[t.Union[str, "ESQLBase"]] = None,
|
|
393
401
|
columnar: t.Optional[bool] = None,
|
|
394
402
|
delimiter: t.Optional[str] = None,
|
|
395
403
|
drop_null_columns: t.Optional[bool] = None,
|
|
@@ -438,7 +446,9 @@ class EsqlClient(NamespacedClient):
|
|
|
438
446
|
`all_columns` which has the name of all columns.
|
|
439
447
|
:param filter: Specify a Query DSL query in the filter parameter to filter the
|
|
440
448
|
set of documents that an ES|QL query runs on.
|
|
441
|
-
:param format: A short version of the Accept header, e.g. json, yaml.
|
|
449
|
+
:param format: A short version of the Accept header, e.g. json, yaml. `csv`,
|
|
450
|
+
`tsv`, and `txt` formats will return results in a tabular format, excluding
|
|
451
|
+
other metadata fields from the response.
|
|
442
452
|
:param include_ccs_metadata: When set to `true` and performing a cross-cluster
|
|
443
453
|
query, the response will include an extra `_clusters` object with information
|
|
444
454
|
about the clusters that participated in the search along with info such as
|
|
@@ -476,7 +486,7 @@ class EsqlClient(NamespacedClient):
|
|
|
476
486
|
__query["pretty"] = pretty
|
|
477
487
|
if not __body:
|
|
478
488
|
if query is not None:
|
|
479
|
-
__body["query"] = query
|
|
489
|
+
__body["query"] = str(query)
|
|
480
490
|
if columnar is not None:
|
|
481
491
|
__body["columnar"] = columnar
|
|
482
492
|
if filter is not None:
|
|
@@ -3715,7 +3715,7 @@ class IndicesClient(NamespacedClient):
|
|
|
3715
3715
|
<li>Change a field's mapping using reindexing</li>
|
|
3716
3716
|
<li>Rename a field using a field alias</li>
|
|
3717
3717
|
</ul>
|
|
3718
|
-
<p>Learn how to use the update mapping API with practical examples in the <a href="https://www.elastic.co/docs
|
|
3718
|
+
<p>Learn how to use the update mapping API with practical examples in the <a href="https://www.elastic.co/docs/manage-data/data-store/mapping/update-mappings-examples">Update mapping API examples</a> guide.</p>
|
|
3719
3719
|
|
|
3720
3720
|
|
|
3721
3721
|
`<https://www.elastic.co/docs/api/doc/elasticsearch/v9/operation/operation-indices-put-mapping>`_
|
|
@@ -4587,7 +4587,7 @@ class IndicesClient(NamespacedClient):
|
|
|
4587
4587
|
.. raw:: html
|
|
4588
4588
|
|
|
4589
4589
|
<p>Roll over to a new index.
|
|
4590
|
-
TIP:
|
|
4590
|
+
TIP: We recommend using the index lifecycle rollover action to automate rollovers. However, Serverless does not support Index Lifecycle Management (ILM), so don't use this approach in the Serverless context.</p>
|
|
4591
4591
|
<p>The rollover API creates a new index for a data stream or index alias.
|
|
4592
4592
|
The API behavior depends on the rollover target.</p>
|
|
4593
4593
|
<p><strong>Roll over a data stream</strong></p>
|
|
@@ -141,7 +141,9 @@ class LogstashClient(NamespacedClient):
|
|
|
141
141
|
|
|
142
142
|
`<https://www.elastic.co/docs/api/doc/elasticsearch/v9/operation/operation-logstash-put-pipeline>`_
|
|
143
143
|
|
|
144
|
-
:param id: An identifier for the pipeline.
|
|
144
|
+
:param id: An identifier for the pipeline. Pipeline IDs must begin with a letter
|
|
145
|
+
or underscore and contain only letters, underscores, dashes, hyphens and
|
|
146
|
+
numbers.
|
|
145
147
|
:param pipeline:
|
|
146
148
|
"""
|
|
147
149
|
if id in SKIP_IN_PATH:
|
|
@@ -283,7 +283,7 @@ class SqlClient(NamespacedClient):
|
|
|
283
283
|
keep_alive: t.Optional[t.Union[str, t.Literal[-1], t.Literal[0]]] = None,
|
|
284
284
|
keep_on_completion: t.Optional[bool] = None,
|
|
285
285
|
page_timeout: t.Optional[t.Union[str, t.Literal[-1], t.Literal[0]]] = None,
|
|
286
|
-
params: t.Optional[t.
|
|
286
|
+
params: t.Optional[t.Sequence[t.Any]] = None,
|
|
287
287
|
pretty: t.Optional[bool] = None,
|
|
288
288
|
query: t.Optional[str] = None,
|
|
289
289
|
request_timeout: t.Optional[t.Union[str, t.Literal[-1], t.Literal[0]]] = None,
|
|
@@ -602,6 +602,66 @@ class TransformClient(NamespacedClient):
|
|
|
602
602
|
path_parts=__path_parts,
|
|
603
603
|
)
|
|
604
604
|
|
|
605
|
+
@_rewrite_parameters()
|
|
606
|
+
def set_upgrade_mode(
|
|
607
|
+
self,
|
|
608
|
+
*,
|
|
609
|
+
enabled: t.Optional[bool] = None,
|
|
610
|
+
error_trace: t.Optional[bool] = None,
|
|
611
|
+
filter_path: t.Optional[t.Union[str, t.Sequence[str]]] = None,
|
|
612
|
+
human: t.Optional[bool] = None,
|
|
613
|
+
pretty: t.Optional[bool] = None,
|
|
614
|
+
timeout: t.Optional[t.Union[str, t.Literal[-1], t.Literal[0]]] = None,
|
|
615
|
+
) -> ObjectApiResponse[t.Any]:
|
|
616
|
+
"""
|
|
617
|
+
.. raw:: html
|
|
618
|
+
|
|
619
|
+
<p>Set upgrade_mode for transform indices.
|
|
620
|
+
Sets a cluster wide upgrade_mode setting that prepares transform
|
|
621
|
+
indices for an upgrade.
|
|
622
|
+
When upgrading your cluster, in some circumstances you must restart your
|
|
623
|
+
nodes and reindex your transform indices. In those circumstances,
|
|
624
|
+
there must be no transforms running. You can close the transforms,
|
|
625
|
+
do the upgrade, then open all the transforms again. Alternatively,
|
|
626
|
+
you can use this API to temporarily halt tasks associated with the transforms
|
|
627
|
+
and prevent new transforms from opening. You can also use this API
|
|
628
|
+
during upgrades that do not require you to reindex your transform
|
|
629
|
+
indices, though stopping transforms is not a requirement in that case.
|
|
630
|
+
You can see the current value for the upgrade_mode setting by using the get
|
|
631
|
+
transform info API.</p>
|
|
632
|
+
|
|
633
|
+
|
|
634
|
+
`<https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-transform-set-upgrade-mode>`_
|
|
635
|
+
|
|
636
|
+
:param enabled: When `true`, it enables `upgrade_mode` which temporarily halts
|
|
637
|
+
all transform tasks and prohibits new transform tasks from starting.
|
|
638
|
+
:param timeout: The time to wait for the request to be completed.
|
|
639
|
+
"""
|
|
640
|
+
__path_parts: t.Dict[str, str] = {}
|
|
641
|
+
__path = "/_transform/set_upgrade_mode"
|
|
642
|
+
__query: t.Dict[str, t.Any] = {}
|
|
643
|
+
if enabled is not None:
|
|
644
|
+
__query["enabled"] = enabled
|
|
645
|
+
if error_trace is not None:
|
|
646
|
+
__query["error_trace"] = error_trace
|
|
647
|
+
if filter_path is not None:
|
|
648
|
+
__query["filter_path"] = filter_path
|
|
649
|
+
if human is not None:
|
|
650
|
+
__query["human"] = human
|
|
651
|
+
if pretty is not None:
|
|
652
|
+
__query["pretty"] = pretty
|
|
653
|
+
if timeout is not None:
|
|
654
|
+
__query["timeout"] = timeout
|
|
655
|
+
__headers = {"accept": "application/json"}
|
|
656
|
+
return self.perform_request( # type: ignore[return-value]
|
|
657
|
+
"POST",
|
|
658
|
+
__path,
|
|
659
|
+
params=__query,
|
|
660
|
+
headers=__headers,
|
|
661
|
+
endpoint_id="transform.set_upgrade_mode",
|
|
662
|
+
path_parts=__path_parts,
|
|
663
|
+
)
|
|
664
|
+
|
|
605
665
|
@_rewrite_parameters(
|
|
606
666
|
parameter_aliases={"from": "from_"},
|
|
607
667
|
)
|
elasticsearch9/_version.py
CHANGED
elasticsearch9/dsl/__init__.py
CHANGED
|
@@ -38,23 +38,30 @@ from .faceted_search import (
|
|
|
38
38
|
TermsFacet,
|
|
39
39
|
)
|
|
40
40
|
from .field import (
|
|
41
|
+
AggregateMetricDouble,
|
|
42
|
+
Alias,
|
|
41
43
|
Binary,
|
|
42
44
|
Boolean,
|
|
43
45
|
Byte,
|
|
44
46
|
Completion,
|
|
45
47
|
ConstantKeyword,
|
|
48
|
+
CountedKeyword,
|
|
46
49
|
CustomField,
|
|
47
50
|
Date,
|
|
51
|
+
DateNanos,
|
|
48
52
|
DateRange,
|
|
49
53
|
DenseVector,
|
|
50
54
|
Double,
|
|
51
55
|
DoubleRange,
|
|
52
56
|
Field,
|
|
57
|
+
Flattened,
|
|
53
58
|
Float,
|
|
54
59
|
FloatRange,
|
|
55
60
|
GeoPoint,
|
|
56
61
|
GeoShape,
|
|
57
62
|
HalfFloat,
|
|
63
|
+
Histogram,
|
|
64
|
+
IcuCollationKeyword,
|
|
58
65
|
Integer,
|
|
59
66
|
IntegerRange,
|
|
60
67
|
Ip,
|
|
@@ -63,21 +70,28 @@ from .field import (
|
|
|
63
70
|
Keyword,
|
|
64
71
|
Long,
|
|
65
72
|
LongRange,
|
|
73
|
+
MatchOnlyText,
|
|
66
74
|
Murmur3,
|
|
67
75
|
Nested,
|
|
68
76
|
Object,
|
|
77
|
+
Passthrough,
|
|
69
78
|
Percolator,
|
|
70
79
|
Point,
|
|
71
80
|
RangeField,
|
|
72
81
|
RankFeature,
|
|
73
82
|
RankFeatures,
|
|
83
|
+
RankVectors,
|
|
74
84
|
ScaledFloat,
|
|
75
85
|
SearchAsYouType,
|
|
86
|
+
SemanticText,
|
|
76
87
|
Shape,
|
|
77
88
|
Short,
|
|
78
89
|
SparseVector,
|
|
79
90
|
Text,
|
|
80
91
|
TokenCount,
|
|
92
|
+
UnsignedLong,
|
|
93
|
+
Version,
|
|
94
|
+
Wildcard,
|
|
81
95
|
construct_field,
|
|
82
96
|
)
|
|
83
97
|
from .function import SF
|
|
@@ -108,6 +122,8 @@ __all__ = [
|
|
|
108
122
|
"A",
|
|
109
123
|
"Agg",
|
|
110
124
|
"AggResponse",
|
|
125
|
+
"AggregateMetricDouble",
|
|
126
|
+
"Alias",
|
|
111
127
|
"AsyncComposableIndexTemplate",
|
|
112
128
|
"AsyncDocument",
|
|
113
129
|
"AsyncEmptySearch",
|
|
@@ -126,9 +142,11 @@ __all__ = [
|
|
|
126
142
|
"Completion",
|
|
127
143
|
"ComposableIndexTemplate",
|
|
128
144
|
"ConstantKeyword",
|
|
145
|
+
"CountedKeyword",
|
|
129
146
|
"CustomField",
|
|
130
147
|
"Date",
|
|
131
148
|
"DateHistogramFacet",
|
|
149
|
+
"DateNanos",
|
|
132
150
|
"DateRange",
|
|
133
151
|
"DenseVector",
|
|
134
152
|
"Document",
|
|
@@ -142,12 +160,15 @@ __all__ = [
|
|
|
142
160
|
"FacetedResponse",
|
|
143
161
|
"FacetedSearch",
|
|
144
162
|
"Field",
|
|
163
|
+
"Flattened",
|
|
145
164
|
"Float",
|
|
146
165
|
"FloatRange",
|
|
147
166
|
"GeoPoint",
|
|
148
167
|
"GeoShape",
|
|
149
168
|
"HalfFloat",
|
|
169
|
+
"Histogram",
|
|
150
170
|
"HistogramFacet",
|
|
171
|
+
"IcuCollationKeyword",
|
|
151
172
|
"IllegalOperation",
|
|
152
173
|
"Index",
|
|
153
174
|
"IndexTemplate",
|
|
@@ -162,12 +183,14 @@ __all__ = [
|
|
|
162
183
|
"LongRange",
|
|
163
184
|
"M",
|
|
164
185
|
"Mapping",
|
|
186
|
+
"MatchOnlyText",
|
|
165
187
|
"MetaField",
|
|
166
188
|
"MultiSearch",
|
|
167
189
|
"Murmur3",
|
|
168
190
|
"Nested",
|
|
169
191
|
"NestedFacet",
|
|
170
192
|
"Object",
|
|
193
|
+
"Passthrough",
|
|
171
194
|
"Percolator",
|
|
172
195
|
"Point",
|
|
173
196
|
"Q",
|
|
@@ -177,11 +200,13 @@ __all__ = [
|
|
|
177
200
|
"RangeField",
|
|
178
201
|
"RankFeature",
|
|
179
202
|
"RankFeatures",
|
|
203
|
+
"RankVectors",
|
|
180
204
|
"Response",
|
|
181
205
|
"SF",
|
|
182
206
|
"ScaledFloat",
|
|
183
207
|
"Search",
|
|
184
208
|
"SearchAsYouType",
|
|
209
|
+
"SemanticText",
|
|
185
210
|
"Shape",
|
|
186
211
|
"Short",
|
|
187
212
|
"SparseVector",
|
|
@@ -189,9 +214,12 @@ __all__ = [
|
|
|
189
214
|
"Text",
|
|
190
215
|
"TokenCount",
|
|
191
216
|
"UnknownDslObject",
|
|
217
|
+
"UnsignedLong",
|
|
192
218
|
"UpdateByQuery",
|
|
193
219
|
"UpdateByQueryResponse",
|
|
194
220
|
"ValidationException",
|
|
221
|
+
"Version",
|
|
222
|
+
"Wildcard",
|
|
195
223
|
"analyzer",
|
|
196
224
|
"async_connections",
|
|
197
225
|
"char_filter",
|
|
@@ -20,6 +20,7 @@ from typing import (
|
|
|
20
20
|
TYPE_CHECKING,
|
|
21
21
|
Any,
|
|
22
22
|
AsyncIterable,
|
|
23
|
+
AsyncIterator,
|
|
23
24
|
Dict,
|
|
24
25
|
List,
|
|
25
26
|
Optional,
|
|
@@ -42,6 +43,7 @@ from .search import AsyncSearch
|
|
|
42
43
|
|
|
43
44
|
if TYPE_CHECKING:
|
|
44
45
|
from elasticsearch import AsyncElasticsearch
|
|
46
|
+
from elasticsearch.esql.esql import ESQLBase
|
|
45
47
|
|
|
46
48
|
|
|
47
49
|
class AsyncIndexMeta(DocumentMeta):
|
|
@@ -520,3 +522,85 @@ class AsyncDocument(DocumentBase, metaclass=AsyncIndexMeta):
|
|
|
520
522
|
return action
|
|
521
523
|
|
|
522
524
|
return await async_bulk(es, Generate(actions), **kwargs)
|
|
525
|
+
|
|
526
|
+
@classmethod
|
|
527
|
+
async def esql_execute(
|
|
528
|
+
cls,
|
|
529
|
+
query: "ESQLBase",
|
|
530
|
+
return_additional: bool = False,
|
|
531
|
+
ignore_missing_fields: bool = False,
|
|
532
|
+
using: Optional[AsyncUsingType] = None,
|
|
533
|
+
**kwargs: Any,
|
|
534
|
+
) -> AsyncIterator[Union[Self, Tuple[Self, Dict[str, Any]]]]:
|
|
535
|
+
"""
|
|
536
|
+
Execute the given ES|QL query and return an iterator of 2-element tuples,
|
|
537
|
+
where the first element is an instance of this ``Document`` and the
|
|
538
|
+
second a dictionary with any remaining columns requested in the query.
|
|
539
|
+
|
|
540
|
+
:arg query: an ES|QL query object created with the ``esql_from()`` method.
|
|
541
|
+
:arg return_additional: if ``False`` (the default), this method returns
|
|
542
|
+
document objects. If set to ``True``, the method returns tuples with
|
|
543
|
+
a document in the first element and a dictionary with any additional
|
|
544
|
+
columns returned by the query in the second element.
|
|
545
|
+
:arg ignore_missing_fields: if ``False`` (the default), all the fields of
|
|
546
|
+
the document must be present in the query, or else an exception is
|
|
547
|
+
raised. Set to ``True`` to allow missing fields, which will result in
|
|
548
|
+
partially initialized document objects.
|
|
549
|
+
:arg using: connection alias to use, defaults to ``'default'``
|
|
550
|
+
:arg kwargs: additional options for the ``client.esql.query()`` function.
|
|
551
|
+
"""
|
|
552
|
+
es = cls._get_connection(using)
|
|
553
|
+
response = await es.esql.query(query=str(query), **kwargs)
|
|
554
|
+
query_columns = [col["name"] for col in response.body.get("columns", [])]
|
|
555
|
+
|
|
556
|
+
# Here we get the list of columns defined in the document, which are the
|
|
557
|
+
# columns that we will take from each result to assemble the document
|
|
558
|
+
# object.
|
|
559
|
+
# When `for_esql=False` is passed below by default, the list will include
|
|
560
|
+
# nested fields, which ES|QL does not return, causing an error. When passing
|
|
561
|
+
# `ignore_missing_fields=True` the list will be generated with
|
|
562
|
+
# `for_esql=True`, so the error will not occur, but the documents will
|
|
563
|
+
# not have any Nested objects in them.
|
|
564
|
+
doc_fields = set(cls._get_field_names(for_esql=ignore_missing_fields))
|
|
565
|
+
if not ignore_missing_fields and not doc_fields.issubset(set(query_columns)):
|
|
566
|
+
raise ValueError(
|
|
567
|
+
f"Not all fields of {cls.__name__} were returned by the query. "
|
|
568
|
+
"Make sure your document does not use Nested fields, which are "
|
|
569
|
+
"currently not supported in ES|QL. To force the query to be "
|
|
570
|
+
"evaluated in spite of the missing fields, pass set the "
|
|
571
|
+
"ignore_missing_fields=True option in the esql_execute() call."
|
|
572
|
+
)
|
|
573
|
+
non_doc_fields: set[str] = set(query_columns) - doc_fields - {"_id"}
|
|
574
|
+
index_id = query_columns.index("_id")
|
|
575
|
+
|
|
576
|
+
results = response.body.get("values", [])
|
|
577
|
+
for column_values in results:
|
|
578
|
+
# create a dictionary with all the document fields, expanding the
|
|
579
|
+
# dot notation returned by ES|QL into the recursive dictionaries
|
|
580
|
+
# used by Document.from_dict()
|
|
581
|
+
doc_dict: Dict[str, Any] = {}
|
|
582
|
+
for col, val in zip(query_columns, column_values):
|
|
583
|
+
if col in doc_fields:
|
|
584
|
+
cols = col.split(".")
|
|
585
|
+
d = doc_dict
|
|
586
|
+
for c in cols[:-1]:
|
|
587
|
+
if c not in d:
|
|
588
|
+
d[c] = {}
|
|
589
|
+
d = d[c]
|
|
590
|
+
d[cols[-1]] = val
|
|
591
|
+
|
|
592
|
+
# create the document instance
|
|
593
|
+
obj = cls(meta={"_id": column_values[index_id]})
|
|
594
|
+
obj._from_dict(doc_dict)
|
|
595
|
+
|
|
596
|
+
if return_additional:
|
|
597
|
+
# build a dict with any other values included in the response
|
|
598
|
+
other = {
|
|
599
|
+
col: val
|
|
600
|
+
for col, val in zip(query_columns, column_values)
|
|
601
|
+
if col in non_doc_fields
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
yield obj, other
|
|
605
|
+
else:
|
|
606
|
+
yield obj
|
|
@@ -21,6 +21,7 @@ from typing import (
|
|
|
21
21
|
Any,
|
|
22
22
|
Dict,
|
|
23
23
|
Iterable,
|
|
24
|
+
Iterator,
|
|
24
25
|
List,
|
|
25
26
|
Optional,
|
|
26
27
|
Tuple,
|
|
@@ -42,6 +43,7 @@ from .search import Search
|
|
|
42
43
|
|
|
43
44
|
if TYPE_CHECKING:
|
|
44
45
|
from elasticsearch import Elasticsearch
|
|
46
|
+
from elasticsearch.esql.esql import ESQLBase
|
|
45
47
|
|
|
46
48
|
|
|
47
49
|
class IndexMeta(DocumentMeta):
|
|
@@ -512,3 +514,85 @@ class Document(DocumentBase, metaclass=IndexMeta):
|
|
|
512
514
|
return action
|
|
513
515
|
|
|
514
516
|
return bulk(es, Generate(actions), **kwargs)
|
|
517
|
+
|
|
518
|
+
@classmethod
|
|
519
|
+
def esql_execute(
|
|
520
|
+
cls,
|
|
521
|
+
query: "ESQLBase",
|
|
522
|
+
return_additional: bool = False,
|
|
523
|
+
ignore_missing_fields: bool = False,
|
|
524
|
+
using: Optional[UsingType] = None,
|
|
525
|
+
**kwargs: Any,
|
|
526
|
+
) -> Iterator[Union[Self, Tuple[Self, Dict[str, Any]]]]:
|
|
527
|
+
"""
|
|
528
|
+
Execute the given ES|QL query and return an iterator of 2-element tuples,
|
|
529
|
+
where the first element is an instance of this ``Document`` and the
|
|
530
|
+
second a dictionary with any remaining columns requested in the query.
|
|
531
|
+
|
|
532
|
+
:arg query: an ES|QL query object created with the ``esql_from()`` method.
|
|
533
|
+
:arg return_additional: if ``False`` (the default), this method returns
|
|
534
|
+
document objects. If set to ``True``, the method returns tuples with
|
|
535
|
+
a document in the first element and a dictionary with any additional
|
|
536
|
+
columns returned by the query in the second element.
|
|
537
|
+
:arg ignore_missing_fields: if ``False`` (the default), all the fields of
|
|
538
|
+
the document must be present in the query, or else an exception is
|
|
539
|
+
raised. Set to ``True`` to allow missing fields, which will result in
|
|
540
|
+
partially initialized document objects.
|
|
541
|
+
:arg using: connection alias to use, defaults to ``'default'``
|
|
542
|
+
:arg kwargs: additional options for the ``client.esql.query()`` function.
|
|
543
|
+
"""
|
|
544
|
+
es = cls._get_connection(using)
|
|
545
|
+
response = es.esql.query(query=str(query), **kwargs)
|
|
546
|
+
query_columns = [col["name"] for col in response.body.get("columns", [])]
|
|
547
|
+
|
|
548
|
+
# Here we get the list of columns defined in the document, which are the
|
|
549
|
+
# columns that we will take from each result to assemble the document
|
|
550
|
+
# object.
|
|
551
|
+
# When `for_esql=False` is passed below by default, the list will include
|
|
552
|
+
# nested fields, which ES|QL does not return, causing an error. When passing
|
|
553
|
+
# `ignore_missing_fields=True` the list will be generated with
|
|
554
|
+
# `for_esql=True`, so the error will not occur, but the documents will
|
|
555
|
+
# not have any Nested objects in them.
|
|
556
|
+
doc_fields = set(cls._get_field_names(for_esql=ignore_missing_fields))
|
|
557
|
+
if not ignore_missing_fields and not doc_fields.issubset(set(query_columns)):
|
|
558
|
+
raise ValueError(
|
|
559
|
+
f"Not all fields of {cls.__name__} were returned by the query. "
|
|
560
|
+
"Make sure your document does not use Nested fields, which are "
|
|
561
|
+
"currently not supported in ES|QL. To force the query to be "
|
|
562
|
+
"evaluated in spite of the missing fields, pass set the "
|
|
563
|
+
"ignore_missing_fields=True option in the esql_execute() call."
|
|
564
|
+
)
|
|
565
|
+
non_doc_fields: set[str] = set(query_columns) - doc_fields - {"_id"}
|
|
566
|
+
index_id = query_columns.index("_id")
|
|
567
|
+
|
|
568
|
+
results = response.body.get("values", [])
|
|
569
|
+
for column_values in results:
|
|
570
|
+
# create a dictionary with all the document fields, expanding the
|
|
571
|
+
# dot notation returned by ES|QL into the recursive dictionaries
|
|
572
|
+
# used by Document.from_dict()
|
|
573
|
+
doc_dict: Dict[str, Any] = {}
|
|
574
|
+
for col, val in zip(query_columns, column_values):
|
|
575
|
+
if col in doc_fields:
|
|
576
|
+
cols = col.split(".")
|
|
577
|
+
d = doc_dict
|
|
578
|
+
for c in cols[:-1]:
|
|
579
|
+
if c not in d:
|
|
580
|
+
d[c] = {}
|
|
581
|
+
d = d[c]
|
|
582
|
+
d[cols[-1]] = val
|
|
583
|
+
|
|
584
|
+
# create the document instance
|
|
585
|
+
obj = cls(meta={"_id": column_values[index_id]})
|
|
586
|
+
obj._from_dict(doc_dict)
|
|
587
|
+
|
|
588
|
+
if return_additional:
|
|
589
|
+
# build a dict with any other values included in the response
|
|
590
|
+
other = {
|
|
591
|
+
col: val
|
|
592
|
+
for col, val in zip(query_columns, column_values)
|
|
593
|
+
if col in non_doc_fields
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
yield obj, other
|
|
597
|
+
else:
|
|
598
|
+
yield obj
|
elasticsearch9/dsl/aggs.py
CHANGED
|
@@ -643,6 +643,54 @@ class Cardinality(Agg[_R]):
|
|
|
643
643
|
)
|
|
644
644
|
|
|
645
645
|
|
|
646
|
+
class CartesianBounds(Agg[_R]):
|
|
647
|
+
"""
|
|
648
|
+
A metric aggregation that computes the spatial bounding box containing
|
|
649
|
+
all values for a Point or Shape field.
|
|
650
|
+
|
|
651
|
+
:arg field: The field on which to run the aggregation.
|
|
652
|
+
:arg missing: The value to apply to documents that do not have a
|
|
653
|
+
value. By default, documents without a value are ignored.
|
|
654
|
+
:arg script:
|
|
655
|
+
"""
|
|
656
|
+
|
|
657
|
+
name = "cartesian_bounds"
|
|
658
|
+
|
|
659
|
+
def __init__(
|
|
660
|
+
self,
|
|
661
|
+
*,
|
|
662
|
+
field: Union[str, "InstrumentedField", "DefaultType"] = DEFAULT,
|
|
663
|
+
missing: Union[str, int, float, bool, "DefaultType"] = DEFAULT,
|
|
664
|
+
script: Union["types.Script", Dict[str, Any], "DefaultType"] = DEFAULT,
|
|
665
|
+
**kwargs: Any,
|
|
666
|
+
):
|
|
667
|
+
super().__init__(field=field, missing=missing, script=script, **kwargs)
|
|
668
|
+
|
|
669
|
+
|
|
670
|
+
class CartesianCentroid(Agg[_R]):
|
|
671
|
+
"""
|
|
672
|
+
A metric aggregation that computes the weighted centroid from all
|
|
673
|
+
coordinate values for point and shape fields.
|
|
674
|
+
|
|
675
|
+
:arg field: The field on which to run the aggregation.
|
|
676
|
+
:arg missing: The value to apply to documents that do not have a
|
|
677
|
+
value. By default, documents without a value are ignored.
|
|
678
|
+
:arg script:
|
|
679
|
+
"""
|
|
680
|
+
|
|
681
|
+
name = "cartesian_centroid"
|
|
682
|
+
|
|
683
|
+
def __init__(
|
|
684
|
+
self,
|
|
685
|
+
*,
|
|
686
|
+
field: Union[str, "InstrumentedField", "DefaultType"] = DEFAULT,
|
|
687
|
+
missing: Union[str, int, float, bool, "DefaultType"] = DEFAULT,
|
|
688
|
+
script: Union["types.Script", Dict[str, Any], "DefaultType"] = DEFAULT,
|
|
689
|
+
**kwargs: Any,
|
|
690
|
+
):
|
|
691
|
+
super().__init__(field=field, missing=missing, script=script, **kwargs)
|
|
692
|
+
|
|
693
|
+
|
|
646
694
|
class CategorizeText(Bucket[_R]):
|
|
647
695
|
"""
|
|
648
696
|
A multi-bucket aggregation that groups semi-structured text into
|
|
@@ -725,6 +773,43 @@ class CategorizeText(Bucket[_R]):
|
|
|
725
773
|
)
|
|
726
774
|
|
|
727
775
|
|
|
776
|
+
class ChangePoint(Pipeline[_R]):
|
|
777
|
+
"""
|
|
778
|
+
A sibling pipeline that detects, spikes, dips, and change points in a
|
|
779
|
+
metric. Given a distribution of values provided by the sibling multi-
|
|
780
|
+
bucket aggregation, this aggregation indicates the bucket of any spike
|
|
781
|
+
or dip and/or the bucket at which the largest change in the
|
|
782
|
+
distribution of values, if they are statistically significant. There
|
|
783
|
+
must be at least 22 bucketed values. Fewer than 1,000 is preferred.
|
|
784
|
+
|
|
785
|
+
:arg format: `DecimalFormat` pattern for the output value. If
|
|
786
|
+
specified, the formatted value is returned in the aggregation’s
|
|
787
|
+
`value_as_string` property.
|
|
788
|
+
:arg gap_policy: Policy to apply when gaps are found in the data.
|
|
789
|
+
Defaults to `skip` if omitted.
|
|
790
|
+
:arg buckets_path: Path to the buckets that contain one set of values
|
|
791
|
+
to correlate.
|
|
792
|
+
"""
|
|
793
|
+
|
|
794
|
+
name = "change_point"
|
|
795
|
+
|
|
796
|
+
def __init__(
|
|
797
|
+
self,
|
|
798
|
+
*,
|
|
799
|
+
format: Union[str, "DefaultType"] = DEFAULT,
|
|
800
|
+
gap_policy: Union[
|
|
801
|
+
Literal["skip", "insert_zeros", "keep_values"], "DefaultType"
|
|
802
|
+
] = DEFAULT,
|
|
803
|
+
buckets_path: Union[
|
|
804
|
+
str, Sequence[str], Mapping[str, str], "DefaultType"
|
|
805
|
+
] = DEFAULT,
|
|
806
|
+
**kwargs: Any,
|
|
807
|
+
):
|
|
808
|
+
super().__init__(
|
|
809
|
+
format=format, gap_policy=gap_policy, buckets_path=buckets_path, **kwargs
|
|
810
|
+
)
|
|
811
|
+
|
|
812
|
+
|
|
728
813
|
class Children(Bucket[_R]):
|
|
729
814
|
"""
|
|
730
815
|
A single bucket aggregation that selects child documents that have the
|
|
@@ -2960,6 +3045,14 @@ class SignificantTerms(Bucket[_R]):
|
|
|
2960
3045
|
the foreground sample with a term divided by the number of
|
|
2961
3046
|
documents in the background with the term.
|
|
2962
3047
|
:arg script_heuristic: Customized score, implemented via a script.
|
|
3048
|
+
:arg p_value: Significant terms heuristic that calculates the p-value
|
|
3049
|
+
between the term existing in foreground and background sets. The
|
|
3050
|
+
p-value is the probability of obtaining test results at least as
|
|
3051
|
+
extreme as the results actually observed, under the assumption
|
|
3052
|
+
that the null hypothesis is correct. The p-value is calculated
|
|
3053
|
+
assuming that the foreground set and the background set are
|
|
3054
|
+
independent https://en.wikipedia.org/wiki/Bernoulli_trial, with
|
|
3055
|
+
the null hypothesis that the probabilities are the same.
|
|
2963
3056
|
:arg shard_min_doc_count: Regulates the certainty a shard has if the
|
|
2964
3057
|
term should actually be added to the candidate list or not with
|
|
2965
3058
|
respect to the `min_doc_count`. Terms will only be considered if
|
|
@@ -3013,6 +3106,9 @@ class SignificantTerms(Bucket[_R]):
|
|
|
3013
3106
|
script_heuristic: Union[
|
|
3014
3107
|
"types.ScriptedHeuristic", Dict[str, Any], "DefaultType"
|
|
3015
3108
|
] = DEFAULT,
|
|
3109
|
+
p_value: Union[
|
|
3110
|
+
"types.PValueHeuristic", Dict[str, Any], "DefaultType"
|
|
3111
|
+
] = DEFAULT,
|
|
3016
3112
|
shard_min_doc_count: Union[int, "DefaultType"] = DEFAULT,
|
|
3017
3113
|
shard_size: Union[int, "DefaultType"] = DEFAULT,
|
|
3018
3114
|
size: Union[int, "DefaultType"] = DEFAULT,
|
|
@@ -3031,6 +3127,7 @@ class SignificantTerms(Bucket[_R]):
|
|
|
3031
3127
|
mutual_information=mutual_information,
|
|
3032
3128
|
percentage=percentage,
|
|
3033
3129
|
script_heuristic=script_heuristic,
|
|
3130
|
+
p_value=p_value,
|
|
3034
3131
|
shard_min_doc_count=shard_min_doc_count,
|
|
3035
3132
|
shard_size=shard_size,
|
|
3036
3133
|
size=size,
|