Split out Elasticsearch backend functionality out for easier extensibility (#11199, #11018)

Co-authored-by: marcelkornblum <me@marcelkornblum.com>
Co-authored-by: Cameron Lamb <cameron.lamb@digital.trade.gov.uk>
pull/11204/head
Matt Westcott 2023-11-07 14:11:07 +00:00
rodzic 536ad2891e
commit 845a2acb36
4 zmienionych plików z 36 dodań i 22 usunięć

Wyświetl plik

@ -22,6 +22,7 @@ Changelog
* Maintenance: Update djhtml to 3.0.6 (Matt Westcott)
* Maintenance: Migrate the contrib settings edit view to a class-based view (Chiemezuo Akujobi, Sage Abdullah)
* Maintenance: Remove django-pattern-library upper bound in testing dependencies (Sage Abdullah)
* Maintenance: Split up functions in Elasticsearch backend for easier extensibility (Marcel Kornblum, Cameron Lamb, Sam Dudley)
5.2.1 (xx.xx.xxxx) - IN DEVELOPMENT

Wyświetl plik

@ -760,6 +760,9 @@
* Vedant Pandey
* Ian Price
* Elhussein Almasri
* Marcel Kornblum
* Cameron Lamb
* Sam Dudley
## Translators

Wyświetl plik

@ -41,6 +41,7 @@ depth: 1
* Update djhtml to 3.0.6 (Matt Westcott)
* Migrate the contrib settings edit view to a class-based view (Chiemezuo Akujobi, Sage Abdullah)
* Remove django-pattern-library upper bound in testing dependencies (Sage Abdullah)
* Split up functions in Elasticsearch backend for easier extensibility (Marcel Kornblum, Cameron Lamb, Sam Dudley)
## Upgrade considerations - changes affecting all projects

Wyświetl plik

@ -449,23 +449,23 @@ class Elasticsearch7SearchQueryCompiler(BaseSearchQueryCompiler):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.mapping = self.mapping_class(self.queryset.model)
self.remapped_fields = self._remap_fields(self.fields)
# Convert field names into index column names
if self.fields:
self.remapped_fields = []
searchable_fields = {
f.field_name: f
for f in self.queryset.model.get_searchable_search_fields()
}
for field_name in self.fields:
def _remap_fields(self, fields):
"""Convert field names into index column names and add boosts."""
remapped_fields = []
if fields:
searchable_fields = {f.field_name: f for f in self.get_searchable_fields()}
for field_name in fields:
if field_name in searchable_fields:
field_name = self.mapping.get_field_column_name(
searchable_fields[field_name]
)
self.remapped_fields.append(Field(field_name))
remapped_fields.append(Field(field_name))
else:
self.remapped_fields = [Field(self.mapping.all_field_name)]
remapped_fields.append(Field(self.mapping.all_field_name))
models = get_indexed_models()
unique_boosts = set()
@ -474,13 +474,15 @@ class Elasticsearch7SearchQueryCompiler(BaseSearchQueryCompiler):
if field.boost:
unique_boosts.add(float(field.boost))
self.remapped_fields.extend(
remapped_fields.extend(
[
Field(self.mapping.get_boost_field_name(boost), boost)
for boost in unique_boosts
]
)
return remapped_fields
def get_boosted_fields(self, fields):
boosted_fields = []
if not isinstance(fields, list):
@ -717,17 +719,20 @@ class Elasticsearch7SearchQueryCompiler(BaseSearchQueryCompiler):
}
else:
if len(fields) == 1:
return self._compile_query(self.query, fields[0])
else:
# Compile a query for each field then combine with disjunction
# max (or operator which takes the max score out of each of the
# field queries)
field_queries = []
for field in fields:
field_queries.append(self._compile_query(self.query, field))
return self._join_and_compile_queries(self.query, fields)
return {"dis_max": {"queries": field_queries}}
def _join_and_compile_queries(self, query, fields, boost=1.0):
if len(fields) == 1:
return self._compile_query(query, fields[0], boost)
else:
# Compile a query for each field then combine with disjunction
# max (or operator which takes the max score out of each of the
# field queries)
field_queries = []
for field in fields:
field_queries.append(self._compile_query(query, field, boost))
return {"dis_max": {"queries": field_queries}}
def get_content_type_filter(self):
# Query content_type using a "match" query. See comment in
@ -768,6 +773,9 @@ class Elasticsearch7SearchQueryCompiler(BaseSearchQueryCompiler):
else:
return inner_query
def get_searchable_fields(self):
return self.queryset.model.get_searchable_search_fields()
def get_sort(self):
# Ordering by relevance is the default in Elasticsearch
if self.order_by_relevance:
@ -1171,7 +1179,8 @@ class Elasticsearch7SearchBackend(BaseSearchBackend):
def _get_options_from_host_urls(self, urls):
"""Given a list of parsed URLs, return a dict of additional options to be passed into the
Elasticsearch constructor; necessary for options that aren't valid as part of the 'hosts' config"""
Elasticsearch constructor; necessary for options that aren't valid as part of the 'hosts' config
"""
return {}
def __init__(self, params):