elasticsearch 9.0.0__py3-none-any.whl → 9.0.2__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.
Files changed (29) hide show
  1. elasticsearch/_async/client/__init__.py +5 -5
  2. elasticsearch/_async/client/cat.py +201 -7
  3. elasticsearch/_async/client/indices.py +16 -7
  4. elasticsearch/_async/client/inference.py +2 -72
  5. elasticsearch/_async/client/ml.py +3 -3
  6. elasticsearch/_sync/client/__init__.py +5 -5
  7. elasticsearch/_sync/client/cat.py +201 -7
  8. elasticsearch/_sync/client/indices.py +16 -7
  9. elasticsearch/_sync/client/inference.py +2 -72
  10. elasticsearch/_sync/client/ml.py +3 -3
  11. elasticsearch/_version.py +1 -1
  12. elasticsearch/dsl/_async/document.py +1 -1
  13. elasticsearch/dsl/_sync/_sync_check/__init__.py +16 -0
  14. elasticsearch/dsl/_sync/_sync_check/document.py +514 -0
  15. elasticsearch/dsl/_sync/_sync_check/faceted_search.py +50 -0
  16. elasticsearch/dsl/_sync/_sync_check/index.py +597 -0
  17. elasticsearch/dsl/_sync/_sync_check/mapping.py +49 -0
  18. elasticsearch/dsl/_sync/_sync_check/search.py +230 -0
  19. elasticsearch/dsl/_sync/_sync_check/update_by_query.py +45 -0
  20. elasticsearch/dsl/_sync/document.py +1 -1
  21. elasticsearch/dsl/field.py +11 -1
  22. elasticsearch/dsl/query.py +44 -2
  23. elasticsearch/dsl/types.py +76 -10
  24. elasticsearch/exceptions.py +2 -0
  25. {elasticsearch-9.0.0.dist-info → elasticsearch-9.0.2.dist-info}/METADATA +15 -16
  26. {elasticsearch-9.0.0.dist-info → elasticsearch-9.0.2.dist-info}/RECORD +29 -22
  27. {elasticsearch-9.0.0.dist-info → elasticsearch-9.0.2.dist-info}/WHEEL +0 -0
  28. {elasticsearch-9.0.0.dist-info → elasticsearch-9.0.2.dist-info}/licenses/LICENSE +0 -0
  29. {elasticsearch-9.0.0.dist-info → elasticsearch-9.0.2.dist-info}/licenses/NOTICE +0 -0
@@ -0,0 +1,597 @@
1
+ # Licensed to Elasticsearch B.V. under one or more contributor
2
+ # license agreements. See the NOTICE file distributed with
3
+ # this work for additional information regarding copyright
4
+ # ownership. Elasticsearch B.V. licenses this file to you under
5
+ # the Apache License, Version 2.0 (the "License"); you may
6
+ # not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing,
12
+ # software distributed under the License is distributed on an
13
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
+ # KIND, either express or implied. See the License for the
15
+ # specific language governing permissions and limitations
16
+ # under the License.
17
+
18
+ from typing import TYPE_CHECKING, Any, Dict, Optional
19
+
20
+ from typing_extensions import Self
21
+
22
+ from ..connections import get_connection
23
+ from ..exceptions import IllegalOperation
24
+ from ..index_base import IndexBase
25
+ from ..utils import UsingType
26
+ from .mapping import Mapping
27
+ from .search import Search
28
+ from .update_by_query import UpdateByQuery
29
+
30
+ if TYPE_CHECKING:
31
+ from elastic_transport import ObjectApiResponse
32
+
33
+ from elasticsearch import Elasticsearch
34
+
35
+
36
+ class IndexTemplate:
37
+ def __init__(
38
+ self,
39
+ name: str,
40
+ template: str,
41
+ index: Optional["Index"] = None,
42
+ order: Optional[int] = None,
43
+ **kwargs: Any,
44
+ ):
45
+ if index is None:
46
+ self._index = Index(template, **kwargs)
47
+ else:
48
+ if kwargs:
49
+ raise ValueError(
50
+ "You cannot specify options for Index when"
51
+ " passing an Index instance."
52
+ )
53
+ self._index = index.clone()
54
+ self._index._name = template
55
+ self._template_name = name
56
+ self.order = order
57
+
58
+ def __getattr__(self, attr_name: str) -> Any:
59
+ return getattr(self._index, attr_name)
60
+
61
+ def to_dict(self) -> Dict[str, Any]:
62
+ d = self._index.to_dict()
63
+ d["index_patterns"] = [self._index._name]
64
+ if self.order is not None:
65
+ d["order"] = self.order
66
+ return d
67
+
68
+ def save(self, using: Optional[UsingType] = None) -> "ObjectApiResponse[Any]":
69
+ es = get_connection(using or self._index._using)
70
+ return es.indices.put_template(name=self._template_name, body=self.to_dict())
71
+
72
+
73
+ class ComposableIndexTemplate:
74
+ def __init__(
75
+ self,
76
+ name: str,
77
+ template: str,
78
+ index: Optional["Index"] = None,
79
+ priority: Optional[int] = None,
80
+ **kwargs: Any,
81
+ ):
82
+ if index is None:
83
+ self._index = Index(template, **kwargs)
84
+ else:
85
+ if kwargs:
86
+ raise ValueError(
87
+ "You cannot specify options for Index when"
88
+ " passing an Index instance."
89
+ )
90
+ self._index = index.clone()
91
+ self._index._name = template
92
+ self._template_name = name
93
+ self.priority = priority
94
+
95
+ def __getattr__(self, attr_name: str) -> Any:
96
+ return getattr(self._index, attr_name)
97
+
98
+ def to_dict(self) -> Dict[str, Any]:
99
+ d: Dict[str, Any] = {"template": self._index.to_dict()}
100
+ d["index_patterns"] = [self._index._name]
101
+ if self.priority is not None:
102
+ d["priority"] = self.priority
103
+ return d
104
+
105
+ def save(self, using: Optional[UsingType] = None) -> "ObjectApiResponse[Any]":
106
+ es = get_connection(using or self._index._using)
107
+ return es.indices.put_index_template(name=self._template_name, **self.to_dict())
108
+
109
+
110
+ class Index(IndexBase):
111
+ _using: UsingType
112
+
113
+ if TYPE_CHECKING:
114
+
115
+ def get_or_create_mapping(self) -> Mapping: ...
116
+
117
+ def __init__(self, name: str, using: UsingType = "default"):
118
+ """
119
+ :arg name: name of the index
120
+ :arg using: connection alias to use, defaults to ``'default'``
121
+ """
122
+ super().__init__(name, Mapping, using=using)
123
+
124
+ def _get_connection(self, using: Optional[UsingType] = None) -> "Elasticsearch":
125
+ if self._name is None:
126
+ raise ValueError("You cannot perform API calls on the default index.")
127
+ return get_connection(using or self._using)
128
+
129
+ connection = property(_get_connection)
130
+
131
+ def as_template(
132
+ self,
133
+ template_name: str,
134
+ pattern: Optional[str] = None,
135
+ order: Optional[int] = None,
136
+ ) -> IndexTemplate:
137
+ return IndexTemplate(
138
+ template_name, pattern or self._name, index=self, order=order
139
+ )
140
+
141
+ def as_composable_template(
142
+ self,
143
+ template_name: str,
144
+ pattern: Optional[str] = None,
145
+ priority: Optional[int] = None,
146
+ ) -> ComposableIndexTemplate:
147
+ return ComposableIndexTemplate(
148
+ template_name, pattern or self._name, index=self, priority=priority
149
+ )
150
+
151
+ def load_mappings(self, using: Optional[UsingType] = None) -> None:
152
+ self.get_or_create_mapping().update_from_es(
153
+ self._name, using=using or self._using
154
+ )
155
+
156
+ def clone(
157
+ self, name: Optional[str] = None, using: Optional[UsingType] = None
158
+ ) -> Self:
159
+ """
160
+ Create a copy of the instance with another name or connection alias.
161
+ Useful for creating multiple indices with shared configuration::
162
+
163
+ i = Index('base-index')
164
+ i.settings(number_of_shards=1)
165
+ i.create()
166
+
167
+ i2 = i.clone('other-index')
168
+ i2.create()
169
+
170
+ :arg name: name of the index
171
+ :arg using: connection alias to use, defaults to ``'default'``
172
+ """
173
+ i = self.__class__(name or self._name, using=using or self._using)
174
+ i._settings = self._settings.copy()
175
+ i._aliases = self._aliases.copy()
176
+ i._analysis = self._analysis.copy()
177
+ i._doc_types = self._doc_types[:]
178
+ if self._mapping is not None:
179
+ i._mapping = self._mapping._clone()
180
+ return i
181
+
182
+ def search(self, using: Optional[UsingType] = None) -> Search:
183
+ """
184
+ Return a :class:`~elasticsearch.dsl.Search` object searching over the
185
+ index (or all the indices belonging to this template) and its
186
+ ``Document``\\s.
187
+ """
188
+ return Search(
189
+ using=using or self._using, index=self._name, doc_type=self._doc_types
190
+ )
191
+
192
+ def updateByQuery(self, using: Optional[UsingType] = None) -> UpdateByQuery:
193
+ """
194
+ Return a :class:`~elasticsearch.dsl.UpdateByQuery` object searching over the index
195
+ (or all the indices belonging to this template) and updating Documents that match
196
+ the search criteria.
197
+
198
+ For more information, see here:
199
+ https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-update-by-query.html
200
+ """
201
+ return UpdateByQuery(
202
+ using=using or self._using,
203
+ index=self._name,
204
+ )
205
+
206
+ def create(
207
+ self, using: Optional[UsingType] = None, **kwargs: Any
208
+ ) -> "ObjectApiResponse[Any]":
209
+ """
210
+ Creates the index in elasticsearch.
211
+
212
+ Any additional keyword arguments will be passed to
213
+ ``Elasticsearch.indices.create`` unchanged.
214
+ """
215
+ return self._get_connection(using).indices.create(
216
+ index=self._name, body=self.to_dict(), **kwargs
217
+ )
218
+
219
+ def is_closed(self, using: Optional[UsingType] = None) -> bool:
220
+ state = self._get_connection(using).cluster.state(
221
+ index=self._name, metric="metadata"
222
+ )
223
+ return bool(state["metadata"]["indices"][self._name]["state"] == "close")
224
+
225
+ def save(
226
+ self, using: Optional[UsingType] = None
227
+ ) -> "Optional[ObjectApiResponse[Any]]":
228
+ """
229
+ Sync the index definition with elasticsearch, creating the index if it
230
+ doesn't exist and updating its settings and mappings if it does.
231
+
232
+ Note some settings and mapping changes cannot be done on an open
233
+ index (or at all on an existing index) and for those this method will
234
+ fail with the underlying exception.
235
+ """
236
+ if not self.exists(using=using):
237
+ return self.create(using=using)
238
+
239
+ body = self.to_dict()
240
+ settings = body.pop("settings", {})
241
+ analysis = settings.pop("analysis", None)
242
+ current_settings = (self.get_settings(using=using))[self._name]["settings"][
243
+ "index"
244
+ ]
245
+ if analysis:
246
+ if self.is_closed(using=using):
247
+ # closed index, update away
248
+ settings["analysis"] = analysis
249
+ else:
250
+ # compare analysis definition, if all analysis objects are
251
+ # already defined as requested, skip analysis update and
252
+ # proceed, otherwise raise IllegalOperation
253
+ existing_analysis = current_settings.get("analysis", {})
254
+ if any(
255
+ existing_analysis.get(section, {}).get(k, None)
256
+ != analysis[section][k]
257
+ for section in analysis
258
+ for k in analysis[section]
259
+ ):
260
+ raise IllegalOperation(
261
+ "You cannot update analysis configuration on an open index, "
262
+ "you need to close index %s first." % self._name
263
+ )
264
+
265
+ # try and update the settings
266
+ if settings:
267
+ settings = settings.copy()
268
+ for k, v in list(settings.items()):
269
+ if k in current_settings and current_settings[k] == str(v):
270
+ del settings[k]
271
+
272
+ if settings:
273
+ self.put_settings(using=using, body=settings)
274
+
275
+ # update the mappings, any conflict in the mappings will result in an
276
+ # exception
277
+ mappings = body.pop("mappings", {})
278
+ if mappings:
279
+ return self.put_mapping(using=using, body=mappings)
280
+
281
+ return None
282
+
283
+ def analyze(
284
+ self, using: Optional[UsingType] = None, **kwargs: Any
285
+ ) -> "ObjectApiResponse[Any]":
286
+ """
287
+ Perform the analysis process on a text and return the tokens breakdown
288
+ of the text.
289
+
290
+ Any additional keyword arguments will be passed to
291
+ ``Elasticsearch.indices.analyze`` unchanged.
292
+ """
293
+ return self._get_connection(using).indices.analyze(index=self._name, **kwargs)
294
+
295
+ def refresh(
296
+ self, using: Optional[UsingType] = None, **kwargs: Any
297
+ ) -> "ObjectApiResponse[Any]":
298
+ """
299
+ Performs a refresh operation on the index.
300
+
301
+ Any additional keyword arguments will be passed to
302
+ ``Elasticsearch.indices.refresh`` unchanged.
303
+ """
304
+ return self._get_connection(using).indices.refresh(index=self._name, **kwargs)
305
+
306
+ def flush(
307
+ self, using: Optional[UsingType] = None, **kwargs: Any
308
+ ) -> "ObjectApiResponse[Any]":
309
+ """
310
+ Performs a flush operation on the index.
311
+
312
+ Any additional keyword arguments will be passed to
313
+ ``Elasticsearch.indices.flush`` unchanged.
314
+ """
315
+ return self._get_connection(using).indices.flush(index=self._name, **kwargs)
316
+
317
+ def get(
318
+ self, using: Optional[UsingType] = None, **kwargs: Any
319
+ ) -> "ObjectApiResponse[Any]":
320
+ """
321
+ The get index API allows to retrieve information about the index.
322
+
323
+ Any additional keyword arguments will be passed to
324
+ ``Elasticsearch.indices.get`` unchanged.
325
+ """
326
+ return self._get_connection(using).indices.get(index=self._name, **kwargs)
327
+
328
+ def open(
329
+ self, using: Optional[UsingType] = None, **kwargs: Any
330
+ ) -> "ObjectApiResponse[Any]":
331
+ """
332
+ Opens the index in elasticsearch.
333
+
334
+ Any additional keyword arguments will be passed to
335
+ ``Elasticsearch.indices.open`` unchanged.
336
+ """
337
+ return self._get_connection(using).indices.open(index=self._name, **kwargs)
338
+
339
+ def close(
340
+ self, using: Optional[UsingType] = None, **kwargs: Any
341
+ ) -> "ObjectApiResponse[Any]":
342
+ """
343
+ Closes the index in elasticsearch.
344
+
345
+ Any additional keyword arguments will be passed to
346
+ ``Elasticsearch.indices.close`` unchanged.
347
+ """
348
+ return self._get_connection(using).indices.close(index=self._name, **kwargs)
349
+
350
+ def delete(
351
+ self, using: Optional[UsingType] = None, **kwargs: Any
352
+ ) -> "ObjectApiResponse[Any]":
353
+ """
354
+ Deletes the index in elasticsearch.
355
+
356
+ Any additional keyword arguments will be passed to
357
+ ``Elasticsearch.indices.delete`` unchanged.
358
+ """
359
+ return self._get_connection(using).indices.delete(index=self._name, **kwargs)
360
+
361
+ def exists(self, using: Optional[UsingType] = None, **kwargs: Any) -> bool:
362
+ """
363
+ Returns ``True`` if the index already exists in elasticsearch.
364
+
365
+ Any additional keyword arguments will be passed to
366
+ ``Elasticsearch.indices.exists`` unchanged.
367
+ """
368
+ return bool(
369
+ self._get_connection(using).indices.exists(index=self._name, **kwargs)
370
+ )
371
+
372
+ def put_mapping(
373
+ self, using: Optional[UsingType] = None, **kwargs: Any
374
+ ) -> "ObjectApiResponse[Any]":
375
+ """
376
+ Register specific mapping definition for a specific type.
377
+
378
+ Any additional keyword arguments will be passed to
379
+ ``Elasticsearch.indices.put_mapping`` unchanged.
380
+ """
381
+ return self._get_connection(using).indices.put_mapping(
382
+ index=self._name, **kwargs
383
+ )
384
+
385
+ def get_mapping(
386
+ self, using: Optional[UsingType] = None, **kwargs: Any
387
+ ) -> "ObjectApiResponse[Any]":
388
+ """
389
+ Retrieve specific mapping definition for a specific type.
390
+
391
+ Any additional keyword arguments will be passed to
392
+ ``Elasticsearch.indices.get_mapping`` unchanged.
393
+ """
394
+ return self._get_connection(using).indices.get_mapping(
395
+ index=self._name, **kwargs
396
+ )
397
+
398
+ def get_field_mapping(
399
+ self, using: Optional[UsingType] = None, **kwargs: Any
400
+ ) -> "ObjectApiResponse[Any]":
401
+ """
402
+ Retrieve mapping definition of a specific field.
403
+
404
+ Any additional keyword arguments will be passed to
405
+ ``Elasticsearch.indices.get_field_mapping`` unchanged.
406
+ """
407
+ return self._get_connection(using).indices.get_field_mapping(
408
+ index=self._name, **kwargs
409
+ )
410
+
411
+ def put_alias(
412
+ self, using: Optional[UsingType] = None, **kwargs: Any
413
+ ) -> "ObjectApiResponse[Any]":
414
+ """
415
+ Create an alias for the index.
416
+
417
+ Any additional keyword arguments will be passed to
418
+ ``Elasticsearch.indices.put_alias`` unchanged.
419
+ """
420
+ return self._get_connection(using).indices.put_alias(index=self._name, **kwargs)
421
+
422
+ def exists_alias(self, using: Optional[UsingType] = None, **kwargs: Any) -> bool:
423
+ """
424
+ Return a boolean indicating whether given alias exists for this index.
425
+
426
+ Any additional keyword arguments will be passed to
427
+ ``Elasticsearch.indices.exists_alias`` unchanged.
428
+ """
429
+ return bool(
430
+ self._get_connection(using).indices.exists_alias(index=self._name, **kwargs)
431
+ )
432
+
433
+ def get_alias(
434
+ self, using: Optional[UsingType] = None, **kwargs: Any
435
+ ) -> "ObjectApiResponse[Any]":
436
+ """
437
+ Retrieve a specified alias.
438
+
439
+ Any additional keyword arguments will be passed to
440
+ ``Elasticsearch.indices.get_alias`` unchanged.
441
+ """
442
+ return self._get_connection(using).indices.get_alias(index=self._name, **kwargs)
443
+
444
+ def delete_alias(
445
+ self, using: Optional[UsingType] = None, **kwargs: Any
446
+ ) -> "ObjectApiResponse[Any]":
447
+ """
448
+ Delete specific alias.
449
+
450
+ Any additional keyword arguments will be passed to
451
+ ``Elasticsearch.indices.delete_alias`` unchanged.
452
+ """
453
+ return self._get_connection(using).indices.delete_alias(
454
+ index=self._name, **kwargs
455
+ )
456
+
457
+ def get_settings(
458
+ self, using: Optional[UsingType] = None, **kwargs: Any
459
+ ) -> "ObjectApiResponse[Any]":
460
+ """
461
+ Retrieve settings for the index.
462
+
463
+ Any additional keyword arguments will be passed to
464
+ ``Elasticsearch.indices.get_settings`` unchanged.
465
+ """
466
+ return self._get_connection(using).indices.get_settings(
467
+ index=self._name, **kwargs
468
+ )
469
+
470
+ def put_settings(
471
+ self, using: Optional[UsingType] = None, **kwargs: Any
472
+ ) -> "ObjectApiResponse[Any]":
473
+ """
474
+ Change specific index level settings in real time.
475
+
476
+ Any additional keyword arguments will be passed to
477
+ ``Elasticsearch.indices.put_settings`` unchanged.
478
+ """
479
+ return self._get_connection(using).indices.put_settings(
480
+ index=self._name, **kwargs
481
+ )
482
+
483
+ def stats(
484
+ self, using: Optional[UsingType] = None, **kwargs: Any
485
+ ) -> "ObjectApiResponse[Any]":
486
+ """
487
+ Retrieve statistics on different operations happening on the index.
488
+
489
+ Any additional keyword arguments will be passed to
490
+ ``Elasticsearch.indices.stats`` unchanged.
491
+ """
492
+ return self._get_connection(using).indices.stats(index=self._name, **kwargs)
493
+
494
+ def segments(
495
+ self, using: Optional[UsingType] = None, **kwargs: Any
496
+ ) -> "ObjectApiResponse[Any]":
497
+ """
498
+ Provide low level segments information that a Lucene index (shard
499
+ level) is built with.
500
+
501
+ Any additional keyword arguments will be passed to
502
+ ``Elasticsearch.indices.segments`` unchanged.
503
+ """
504
+ return self._get_connection(using).indices.segments(index=self._name, **kwargs)
505
+
506
+ def validate_query(
507
+ self, using: Optional[UsingType] = None, **kwargs: Any
508
+ ) -> "ObjectApiResponse[Any]":
509
+ """
510
+ Validate a potentially expensive query without executing it.
511
+
512
+ Any additional keyword arguments will be passed to
513
+ ``Elasticsearch.indices.validate_query`` unchanged.
514
+ """
515
+ return self._get_connection(using).indices.validate_query(
516
+ index=self._name, **kwargs
517
+ )
518
+
519
+ def clear_cache(
520
+ self, using: Optional[UsingType] = None, **kwargs: Any
521
+ ) -> "ObjectApiResponse[Any]":
522
+ """
523
+ Clear all caches or specific cached associated with the index.
524
+
525
+ Any additional keyword arguments will be passed to
526
+ ``Elasticsearch.indices.clear_cache`` unchanged.
527
+ """
528
+ return self._get_connection(using).indices.clear_cache(
529
+ index=self._name, **kwargs
530
+ )
531
+
532
+ def recovery(
533
+ self, using: Optional[UsingType] = None, **kwargs: Any
534
+ ) -> "ObjectApiResponse[Any]":
535
+ """
536
+ The indices recovery API provides insight into on-going shard
537
+ recoveries for the index.
538
+
539
+ Any additional keyword arguments will be passed to
540
+ ``Elasticsearch.indices.recovery`` unchanged.
541
+ """
542
+ return self._get_connection(using).indices.recovery(index=self._name, **kwargs)
543
+
544
+ def shard_stores(
545
+ self, using: Optional[UsingType] = None, **kwargs: Any
546
+ ) -> "ObjectApiResponse[Any]":
547
+ """
548
+ Provides store information for shard copies of the index. Store
549
+ information reports on which nodes shard copies exist, the shard copy
550
+ version, indicating how recent they are, and any exceptions encountered
551
+ while opening the shard index or from earlier engine failure.
552
+
553
+ Any additional keyword arguments will be passed to
554
+ ``Elasticsearch.indices.shard_stores`` unchanged.
555
+ """
556
+ return self._get_connection(using).indices.shard_stores(
557
+ index=self._name, **kwargs
558
+ )
559
+
560
+ def forcemerge(
561
+ self, using: Optional[UsingType] = None, **kwargs: Any
562
+ ) -> "ObjectApiResponse[Any]":
563
+ """
564
+ The force merge API allows to force merging of the index through an
565
+ API. The merge relates to the number of segments a Lucene index holds
566
+ within each shard. The force merge operation allows to reduce the
567
+ number of segments by merging them.
568
+
569
+ This call will block until the merge is complete. If the http
570
+ connection is lost, the request will continue in the background, and
571
+ any new requests will block until the previous force merge is complete.
572
+
573
+ Any additional keyword arguments will be passed to
574
+ ``Elasticsearch.indices.forcemerge`` unchanged.
575
+ """
576
+ return self._get_connection(using).indices.forcemerge(
577
+ index=self._name, **kwargs
578
+ )
579
+
580
+ def shrink(
581
+ self, using: Optional[UsingType] = None, **kwargs: Any
582
+ ) -> "ObjectApiResponse[Any]":
583
+ """
584
+ The shrink index API allows you to shrink an existing index into a new
585
+ index with fewer primary shards. The number of primary shards in the
586
+ target index must be a factor of the shards in the source index. For
587
+ example an index with 8 primary shards can be shrunk into 4, 2 or 1
588
+ primary shards or an index with 15 primary shards can be shrunk into 5,
589
+ 3 or 1. If the number of shards in the index is a prime number it can
590
+ only be shrunk into a single primary shard. Before shrinking, a
591
+ (primary or replica) copy of every shard in the index must be present
592
+ on the same node.
593
+
594
+ Any additional keyword arguments will be passed to
595
+ ``Elasticsearch.indices.shrink`` unchanged.
596
+ """
597
+ return self._get_connection(using).indices.shrink(index=self._name, **kwargs)
@@ -0,0 +1,49 @@
1
+ # Licensed to Elasticsearch B.V. under one or more contributor
2
+ # license agreements. See the NOTICE file distributed with
3
+ # this work for additional information regarding copyright
4
+ # ownership. Elasticsearch B.V. licenses this file to you under
5
+ # the Apache License, Version 2.0 (the "License"); you may
6
+ # not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing,
12
+ # software distributed under the License is distributed on an
13
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
+ # KIND, either express or implied. See the License for the
15
+ # specific language governing permissions and limitations
16
+ # under the License.
17
+
18
+ from typing import List, Optional, Union
19
+
20
+ from typing_extensions import Self
21
+
22
+ from ..connections import get_connection
23
+ from ..mapping_base import MappingBase
24
+ from ..utils import UsingType
25
+
26
+
27
+ class Mapping(MappingBase):
28
+ @classmethod
29
+ def from_es(
30
+ cls, index: Optional[Union[str, List[str]]], using: UsingType = "default"
31
+ ) -> Self:
32
+ m = cls()
33
+ m.update_from_es(index, using)
34
+ return m
35
+
36
+ def update_from_es(
37
+ self, index: Optional[Union[str, List[str]]], using: UsingType = "default"
38
+ ) -> None:
39
+ es = get_connection(using)
40
+ raw = es.indices.get_mapping(index=index)
41
+ _, raw = raw.popitem()
42
+ self._update_from_dict(raw["mappings"])
43
+
44
+ def save(self, index: str, using: UsingType = "default") -> None:
45
+ from .index import Index
46
+
47
+ i = Index(index, using=using)
48
+ i.mapping(self)
49
+ i.save()