kopia lustrzana https://github.com/wagtail/wagtail
				
				
				
			Fix Elasticsearch7 backend to work on pre-7.15 library versions
Fixes #7920. Check library version and only patch backend classes with the updated API calls if it's >=7.15.pull/10918/head
							rodzic
							
								
									b60828ac47
								
							
						
					
					
						commit
						9372cb12e2
					
				|  | @ -1,5 +1,6 @@ | ||||||
| from copy import deepcopy | from copy import deepcopy | ||||||
| 
 | 
 | ||||||
|  | from elasticsearch import VERSION as ELASTICSEARCH_VERSION | ||||||
| from elasticsearch import NotFoundError | from elasticsearch import NotFoundError | ||||||
| from elasticsearch.helpers import bulk | from elasticsearch.helpers import bulk | ||||||
| 
 | 
 | ||||||
|  | @ -13,6 +14,8 @@ from wagtail.search.backends.elasticsearch6 import ( | ||||||
| ) | ) | ||||||
| from wagtail.search.index import class_is_indexed | from wagtail.search.index import class_is_indexed | ||||||
| 
 | 
 | ||||||
|  | use_new_elasticsearch_api = ELASTICSEARCH_VERSION >= (7, 15) | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| class Elasticsearch7Mapping(Elasticsearch6Mapping): | class Elasticsearch7Mapping(Elasticsearch6Mapping): | ||||||
|     def get_mapping(self): |     def get_mapping(self): | ||||||
|  | @ -21,17 +24,19 @@ class Elasticsearch7Mapping(Elasticsearch6Mapping): | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class Elasticsearch7Index(Elasticsearch6Index): | class Elasticsearch7Index(Elasticsearch6Index): | ||||||
|     def put(self): |     if use_new_elasticsearch_api: | ||||||
|         self.es.indices.create(index=self.name, **self.backend.settings) |  | ||||||
| 
 | 
 | ||||||
|     def delete(self): |         def put(self): | ||||||
|         try: |             self.es.indices.create(index=self.name, **self.backend.settings) | ||||||
|             self.es.indices.delete(index=self.name) |  | ||||||
|         except NotFoundError: |  | ||||||
|             pass |  | ||||||
| 
 | 
 | ||||||
|     def refresh(self): |         def delete(self): | ||||||
|         self.es.indices.refresh(index=self.name) |             try: | ||||||
|  |                 self.es.indices.delete(index=self.name) | ||||||
|  |             except NotFoundError: | ||||||
|  |                 pass | ||||||
|  | 
 | ||||||
|  |         def refresh(self): | ||||||
|  |             self.es.indices.refresh(index=self.name) | ||||||
| 
 | 
 | ||||||
|     def add_model(self, model): |     def add_model(self, model): | ||||||
|         # Get mapping |         # Get mapping | ||||||
|  | @ -40,20 +45,36 @@ class Elasticsearch7Index(Elasticsearch6Index): | ||||||
|         # Put mapping |         # Put mapping | ||||||
|         self.es.indices.put_mapping(index=self.name, body=mapping.get_mapping()) |         self.es.indices.put_mapping(index=self.name, body=mapping.get_mapping()) | ||||||
| 
 | 
 | ||||||
|     def add_item(self, item): |     if use_new_elasticsearch_api: | ||||||
|         # Make sure the object can be indexed |  | ||||||
|         if not class_is_indexed(item.__class__): |  | ||||||
|             return |  | ||||||
| 
 | 
 | ||||||
|         # Get mapping |         def add_item(self, item): | ||||||
|         mapping = self.mapping_class(item.__class__) |             # Make sure the object can be indexed | ||||||
|  |             if not class_is_indexed(item.__class__): | ||||||
|  |                 return | ||||||
| 
 | 
 | ||||||
|         # Add document to index |             # Get mapping | ||||||
|         self.es.index( |             mapping = self.mapping_class(item.__class__) | ||||||
|             index=self.name, | 
 | ||||||
|             document=mapping.get_document(item), |             # Add document to index | ||||||
|             id=mapping.get_document_id(item), |             self.es.index( | ||||||
|         ) |                 index=self.name, | ||||||
|  |                 document=mapping.get_document(item), | ||||||
|  |                 id=mapping.get_document_id(item), | ||||||
|  |             ) | ||||||
|  | 
 | ||||||
|  |     else: | ||||||
|  | 
 | ||||||
|  |         def add_item(self, item): | ||||||
|  |             # Make sure the object can be indexed | ||||||
|  |             if not class_is_indexed(item.__class__): | ||||||
|  |                 return | ||||||
|  |             # Get mapping | ||||||
|  |             mapping = self.mapping_class(item.__class__) | ||||||
|  | 
 | ||||||
|  |             # Add document to index | ||||||
|  |             self.es.index( | ||||||
|  |                 self.name, mapping.get_document(item), id=mapping.get_document_id(item) | ||||||
|  |             ) | ||||||
| 
 | 
 | ||||||
|     def add_items(self, model, items): |     def add_items(self, model, items): | ||||||
|         if not class_is_indexed(model): |         if not class_is_indexed(model): | ||||||
|  | @ -93,10 +114,12 @@ class Elasticsearch7SearchQueryCompiler(Elasticsearch6SearchQueryCompiler): | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class Elasticsearch7SearchResults(Elasticsearch6SearchResults): | class Elasticsearch7SearchResults(Elasticsearch6SearchResults): | ||||||
|     def _backend_do_search(self, body, **kwargs): |     if use_new_elasticsearch_api: | ||||||
|         # As of Elasticsearch 7, the 'body' parameter is deprecated; instead, the top-level | 
 | ||||||
|         # keys of the body dict are now kwargs in their own right |         def _backend_do_search(self, body, **kwargs): | ||||||
|         return self.backend.es.search(**body, **kwargs) |             # As of Elasticsearch 7.15, the 'body' parameter is deprecated; instead, the top-level | ||||||
|  |             # keys of the body dict are now kwargs in their own right | ||||||
|  |             return self.backend.es.search(**body, **kwargs) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class Elasticsearch7AutocompleteQueryCompiler( | class Elasticsearch7AutocompleteQueryCompiler( | ||||||
|  |  | ||||||
|  | @ -1,4 +1,5 @@ | ||||||
| from django.core.exceptions import ImproperlyConfigured | from django.core.exceptions import ImproperlyConfigured | ||||||
|  | from elasticsearch import NotFoundError | ||||||
| 
 | 
 | ||||||
| from wagtail.search.backends.elasticsearch7 import ( | from wagtail.search.backends.elasticsearch7 import ( | ||||||
|     Elasticsearch7AutocompleteQueryCompiler, |     Elasticsearch7AutocompleteQueryCompiler, | ||||||
|  | @ -8,6 +9,7 @@ from wagtail.search.backends.elasticsearch7 import ( | ||||||
|     Elasticsearch7SearchQueryCompiler, |     Elasticsearch7SearchQueryCompiler, | ||||||
|     Elasticsearch7SearchResults, |     Elasticsearch7SearchResults, | ||||||
| ) | ) | ||||||
|  | from wagtail.search.index import class_is_indexed | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class Elasticsearch8Mapping(Elasticsearch7Mapping): | class Elasticsearch8Mapping(Elasticsearch7Mapping): | ||||||
|  | @ -15,6 +17,18 @@ class Elasticsearch8Mapping(Elasticsearch7Mapping): | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class Elasticsearch8Index(Elasticsearch7Index): | class Elasticsearch8Index(Elasticsearch7Index): | ||||||
|  |     def put(self): | ||||||
|  |         self.es.indices.create(index=self.name, **self.backend.settings) | ||||||
|  | 
 | ||||||
|  |     def delete(self): | ||||||
|  |         try: | ||||||
|  |             self.es.indices.delete(index=self.name) | ||||||
|  |         except NotFoundError: | ||||||
|  |             pass | ||||||
|  | 
 | ||||||
|  |     def refresh(self): | ||||||
|  |         self.es.indices.refresh(index=self.name) | ||||||
|  | 
 | ||||||
|     def add_model(self, model): |     def add_model(self, model): | ||||||
|         # Get mapping |         # Get mapping | ||||||
|         mapping = self.mapping_class(model) |         mapping = self.mapping_class(model) | ||||||
|  | @ -22,13 +36,31 @@ class Elasticsearch8Index(Elasticsearch7Index): | ||||||
|         # Put mapping |         # Put mapping | ||||||
|         self.es.indices.put_mapping(index=self.name, **mapping.get_mapping()) |         self.es.indices.put_mapping(index=self.name, **mapping.get_mapping()) | ||||||
| 
 | 
 | ||||||
|  |     def add_item(self, item): | ||||||
|  |         # Make sure the object can be indexed | ||||||
|  |         if not class_is_indexed(item.__class__): | ||||||
|  |             return | ||||||
|  | 
 | ||||||
|  |         # Get mapping | ||||||
|  |         mapping = self.mapping_class(item.__class__) | ||||||
|  | 
 | ||||||
|  |         # Add document to index | ||||||
|  |         self.es.index( | ||||||
|  |             index=self.name, | ||||||
|  |             document=mapping.get_document(item), | ||||||
|  |             id=mapping.get_document_id(item), | ||||||
|  |         ) | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| class Elasticsearch8SearchQueryCompiler(Elasticsearch7SearchQueryCompiler): | class Elasticsearch8SearchQueryCompiler(Elasticsearch7SearchQueryCompiler): | ||||||
|     mapping_class = Elasticsearch8Mapping |     mapping_class = Elasticsearch8Mapping | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class Elasticsearch8SearchResults(Elasticsearch7SearchResults): | class Elasticsearch8SearchResults(Elasticsearch7SearchResults): | ||||||
|     pass |     def _backend_do_search(self, body, **kwargs): | ||||||
|  |         # As of Elasticsearch 7.15, the 'body' parameter is deprecated; instead, the top-level | ||||||
|  |         # keys of the body dict are now kwargs in their own right | ||||||
|  |         return self.backend.es.search(**body, **kwargs) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class Elasticsearch8AutocompleteQueryCompiler(Elasticsearch7AutocompleteQueryCompiler): | class Elasticsearch8AutocompleteQueryCompiler(Elasticsearch7AutocompleteQueryCompiler): | ||||||
|  |  | ||||||
|  | @ -20,6 +20,16 @@ except ImportError: | ||||||
|     ELASTICSEARCH_VERSION = (0, 0, 0) |     ELASTICSEARCH_VERSION = (0, 0, 0) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | use_new_elasticsearch_api = ELASTICSEARCH_VERSION >= (7, 15) | ||||||
|  | 
 | ||||||
|  | if use_new_elasticsearch_api: | ||||||
|  |     search_query_kwargs = { | ||||||
|  |         "query": "QUERY", | ||||||
|  |     } | ||||||
|  | else: | ||||||
|  |     search_query_kwargs = {"body": {"query": "QUERY"}} | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| @unittest.skipIf(ELASTICSEARCH_VERSION[0] != 7, "Elasticsearch 7 required") | @unittest.skipIf(ELASTICSEARCH_VERSION[0] != 7, "Elasticsearch 7 required") | ||||||
| class TestElasticsearch7SearchBackend(ElasticsearchCommonSearchBackendTests, TestCase): | class TestElasticsearch7SearchBackend(ElasticsearchCommonSearchBackendTests, TestCase): | ||||||
|     backend_path = "wagtail.search.backends.elasticsearch7" |     backend_path = "wagtail.search.backends.elasticsearch7" | ||||||
|  | @ -915,12 +925,12 @@ class TestElasticsearch7SearchResults(TestCase): | ||||||
|         list(results)  # Performs search |         list(results)  # Performs search | ||||||
| 
 | 
 | ||||||
|         search.assert_any_call( |         search.assert_any_call( | ||||||
|             query="QUERY", |  | ||||||
|             _source=False, |             _source=False, | ||||||
|             stored_fields="pk", |             stored_fields="pk", | ||||||
|             index="wagtail__searchtests_book", |             index="wagtail__searchtests_book", | ||||||
|             scroll="2m", |             scroll="2m", | ||||||
|             size=100, |             size=100, | ||||||
|  |             **search_query_kwargs, | ||||||
|         ) |         ) | ||||||
| 
 | 
 | ||||||
|     @mock.patch("elasticsearch.Elasticsearch.search") |     @mock.patch("elasticsearch.Elasticsearch.search") | ||||||
|  | @ -933,11 +943,11 @@ class TestElasticsearch7SearchResults(TestCase): | ||||||
| 
 | 
 | ||||||
|         search.assert_any_call( |         search.assert_any_call( | ||||||
|             from_=10, |             from_=10, | ||||||
|             query="QUERY", |  | ||||||
|             _source=False, |             _source=False, | ||||||
|             stored_fields="pk", |             stored_fields="pk", | ||||||
|             index="wagtail__searchtests_book", |             index="wagtail__searchtests_book", | ||||||
|             size=1, |             size=1, | ||||||
|  |             **search_query_kwargs, | ||||||
|         ) |         ) | ||||||
| 
 | 
 | ||||||
|     @mock.patch("elasticsearch.Elasticsearch.search") |     @mock.patch("elasticsearch.Elasticsearch.search") | ||||||
|  | @ -949,11 +959,11 @@ class TestElasticsearch7SearchResults(TestCase): | ||||||
| 
 | 
 | ||||||
|         search.assert_any_call( |         search.assert_any_call( | ||||||
|             from_=1, |             from_=1, | ||||||
|             query="QUERY", |  | ||||||
|             _source=False, |             _source=False, | ||||||
|             stored_fields="pk", |             stored_fields="pk", | ||||||
|             index="wagtail__searchtests_book", |             index="wagtail__searchtests_book", | ||||||
|             size=3, |             size=3, | ||||||
|  |             **search_query_kwargs, | ||||||
|         ) |         ) | ||||||
| 
 | 
 | ||||||
|     @mock.patch("elasticsearch.Elasticsearch.search") |     @mock.patch("elasticsearch.Elasticsearch.search") | ||||||
|  | @ -965,11 +975,11 @@ class TestElasticsearch7SearchResults(TestCase): | ||||||
| 
 | 
 | ||||||
|         search.assert_any_call( |         search.assert_any_call( | ||||||
|             from_=10, |             from_=10, | ||||||
|             query="QUERY", |  | ||||||
|             _source=False, |             _source=False, | ||||||
|             stored_fields="pk", |             stored_fields="pk", | ||||||
|             index="wagtail__searchtests_book", |             index="wagtail__searchtests_book", | ||||||
|             size=10, |             size=10, | ||||||
|  |             **search_query_kwargs, | ||||||
|         ) |         ) | ||||||
| 
 | 
 | ||||||
|     @mock.patch("elasticsearch.Elasticsearch.search") |     @mock.patch("elasticsearch.Elasticsearch.search") | ||||||
|  | @ -982,11 +992,11 @@ class TestElasticsearch7SearchResults(TestCase): | ||||||
| 
 | 
 | ||||||
|         search.assert_any_call( |         search.assert_any_call( | ||||||
|             from_=20, |             from_=20, | ||||||
|             query="QUERY", |  | ||||||
|             _source=False, |             _source=False, | ||||||
|             stored_fields="pk", |             stored_fields="pk", | ||||||
|             index="wagtail__searchtests_book", |             index="wagtail__searchtests_book", | ||||||
|             size=1, |             size=1, | ||||||
|  |             **search_query_kwargs, | ||||||
|         ) |         ) | ||||||
| 
 | 
 | ||||||
|     @mock.patch("elasticsearch.Elasticsearch.search") |     @mock.patch("elasticsearch.Elasticsearch.search") | ||||||
|  |  | ||||||
		Ładowanie…
	
		Reference in New Issue
	
	 Matt Westcott
						Matt Westcott