mirror of
https://github.com/Hopiu/wagtail.git
synced 2026-04-24 08:34:49 +00:00
Merge pull request #346 from kaedroho/searchchanges/search-fields-refactor
Search Changes 5 - Use SearchField objects in the backends
This commit is contained in:
commit
ccad0d96ed
3 changed files with 61 additions and 20 deletions
|
|
@ -38,7 +38,7 @@ class DBSearch(BaseSearch):
|
|||
|
||||
# Get fields
|
||||
if fields is None:
|
||||
fields = model.indexed_get_indexed_fields().keys()
|
||||
fields = [field.field_name for field in model.get_searchable_search_fields()]
|
||||
|
||||
# Start will all objects
|
||||
query = model.objects.all()
|
||||
|
|
|
|||
|
|
@ -20,21 +20,17 @@ class ElasticSearchMapping(object):
|
|||
return self.model.indexed_get_content_type()
|
||||
|
||||
def get_mapping(self):
|
||||
# Get type name
|
||||
content_type = self.get_document_type()
|
||||
|
||||
# Get indexed fields
|
||||
indexed_fields = self.model.indexed_get_indexed_fields()
|
||||
|
||||
# Make field list
|
||||
fields = {
|
||||
'pk': dict(type='string', index='not_analyzed', store='yes'),
|
||||
'content_type': dict(type='string'),
|
||||
}
|
||||
fields.update(indexed_fields)
|
||||
|
||||
for field in self.model.get_search_fields():
|
||||
fields[field.get_attname(self.model)] = field.to_dict(self.model)
|
||||
|
||||
return {
|
||||
content_type: {
|
||||
self.get_document_type(): {
|
||||
'properties': fields,
|
||||
}
|
||||
}
|
||||
|
|
@ -43,13 +39,9 @@ class ElasticSearchMapping(object):
|
|||
return obj.indexed_get_toplevel_content_type() + ':' + str(obj.pk)
|
||||
|
||||
def get_document(self, obj):
|
||||
# Get content type, indexed fields and id
|
||||
content_type = obj.indexed_get_content_type()
|
||||
indexed_fields = obj.indexed_get_indexed_fields()
|
||||
|
||||
# Build document
|
||||
doc = dict(pk=str(obj.pk), content_type=content_type)
|
||||
for field in indexed_fields.keys():
|
||||
doc = dict(pk=str(obj.pk), content_type=self.model.indexed_get_content_type())
|
||||
for field in [field.get_attname(self.model) for field in self.model.get_search_fields()]:
|
||||
if hasattr(obj, field):
|
||||
doc[field] = getattr(obj, field)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
import warnings
|
||||
|
||||
from six import string_types
|
||||
|
||||
from django.db import models
|
||||
|
|
@ -35,11 +37,6 @@ class Indexed(object):
|
|||
|
||||
@classmethod
|
||||
def indexed_get_indexed_fields(cls):
|
||||
# New way
|
||||
if hasattr(cls, 'search_fields'):
|
||||
return dict((field.get_attname(cls), field.to_dict(cls)) for field in cls.search_fields)
|
||||
|
||||
# Old way
|
||||
# Get indexed fields for this class as dictionary
|
||||
indexed_fields = cls.indexed_fields
|
||||
if isinstance(indexed_fields, dict):
|
||||
|
|
@ -65,10 +62,57 @@ class Indexed(object):
|
|||
indexed_fields = parent_indexed_fields
|
||||
return indexed_fields
|
||||
|
||||
@classmethod
|
||||
def get_search_fields(cls):
|
||||
search_fields = []
|
||||
|
||||
if hasattr(cls, 'search_fields'):
|
||||
search_fields.extend(cls.search_fields)
|
||||
|
||||
# Backwards compatibility with old indexed_fields setting
|
||||
|
||||
# Get indexed fields
|
||||
indexed_fields = cls.indexed_get_indexed_fields()
|
||||
|
||||
# Display deprecation warning if indexed_fields has been used
|
||||
if indexed_fields:
|
||||
warnings.warn("'indexed_fields' setting is now deprecated."
|
||||
"Use 'search_fields' instead.", DeprecationWarning)
|
||||
|
||||
# Convert them into search fields
|
||||
for field_name, _config in indexed_fields.items():
|
||||
# Copy the config to prevent is trashing anything accidentally
|
||||
config = _config.copy()
|
||||
|
||||
# Check if this is a filter field
|
||||
if config.get('index', None) == 'not_analyzed':
|
||||
config.pop('index')
|
||||
search_fields.append(FilterField(field_name, es_extra=config))
|
||||
continue
|
||||
|
||||
# Must be a search field, check for boosting and partial matching
|
||||
boost = config.pop('boost', None)
|
||||
|
||||
partial_match = False
|
||||
if config.get('analyzer', None) == 'edgengram_analyzer':
|
||||
partial_match = True
|
||||
config.pop('analyzer')
|
||||
|
||||
# Add the field
|
||||
search_fields.append(SearchField(field_name, boost=boost, partial_match=partial_match, es_extra=config))
|
||||
|
||||
return search_fields
|
||||
|
||||
@classmethod
|
||||
def get_searchable_search_fields(cls):
|
||||
return filter(lambda field: field.searchable, cls.get_search_fields())
|
||||
|
||||
indexed_fields = ()
|
||||
|
||||
|
||||
class BaseField(object):
|
||||
searchable = False
|
||||
|
||||
def __init__(self, field_name, **kwargs):
|
||||
self.field_name = field_name
|
||||
self.kwargs = kwargs
|
||||
|
|
@ -94,8 +138,13 @@ class BaseField(object):
|
|||
|
||||
return dic
|
||||
|
||||
def __repr__(self):
|
||||
return "<%s: %s>" % (self.__class__.__name__, self.field_name)
|
||||
|
||||
|
||||
class SearchField(BaseField):
|
||||
searchable = True
|
||||
|
||||
def __init__(self, field_name, boost=None, partial_match=False, **kwargs):
|
||||
super(SearchField, self).__init__(field_name, **kwargs)
|
||||
self.boost = boost
|
||||
|
|
|
|||
Loading…
Reference in a new issue