Merge pull request #346 from kaedroho/searchchanges/search-fields-refactor

Search Changes 5 - Use SearchField objects in the backends
This commit is contained in:
Matt Westcott 2014-07-07 18:43:32 +01:00
commit ccad0d96ed
3 changed files with 61 additions and 20 deletions

View file

@ -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()

View file

@ -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)

View file

@ -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