mirror of
https://github.com/Hopiu/wagtail.git
synced 2026-05-12 01:03:11 +00:00
Moved search method into base search backend
This commit is contained in:
parent
001fcabb46
commit
08ced063ff
4 changed files with 48 additions and 60 deletions
|
|
@ -514,7 +514,7 @@ class Page(six.with_metaclass(PageBase, MP_Node, ClusterableModel, indexed.Index
|
|||
|
||||
# Search
|
||||
s = get_search_backend()
|
||||
return s.search(query_string, model=cls, fields=fields, filters=filters, prefetch_related=prefetch_related)
|
||||
return s.search(query_string, cls, fields=fields, filters=filters, prefetch_related=prefetch_related)
|
||||
|
||||
@classmethod
|
||||
def clean_subpage_types(cls):
|
||||
|
|
|
|||
|
|
@ -1,6 +1,9 @@
|
|||
from django.db import models
|
||||
from django.db.models.query import QuerySet
|
||||
from django.core.exceptions import ImproperlyConfigured
|
||||
|
||||
from wagtail.wagtailsearch.indexed import Indexed
|
||||
from wagtail.wagtailsearch.utils import normalise_query_string
|
||||
|
||||
|
||||
class BaseSearch(object):
|
||||
|
|
@ -32,5 +35,38 @@ class BaseSearch(object):
|
|||
def delete(self, obj):
|
||||
return NotImplemented
|
||||
|
||||
def search(self, query_string, model, fields=None, filters={}, prefetch_related=[]):
|
||||
def _search(self, queryset, query_string, fields=None):
|
||||
return NotImplemented
|
||||
|
||||
def search(self, query_string, model_or_queryset, fields=None, filters=None, prefetch_related=None):
|
||||
# Find model/queryset
|
||||
if isinstance(model_or_queryset, QuerySet):
|
||||
model = model_or_queryset.model
|
||||
queryset = model_or_queryset
|
||||
else:
|
||||
model = model_or_queryset
|
||||
queryset = model_or_queryset.objects.all()
|
||||
|
||||
# Model must be a descendant of Indexed and be a django model
|
||||
if not issubclass(model, Indexed) or not issubclass(model, models.Model):
|
||||
return []
|
||||
|
||||
# Normalise query string
|
||||
if query_string is not None:
|
||||
query_string = normalise_query_string(query_string)
|
||||
|
||||
# Check that theres still a query string after the clean up
|
||||
if query_string == "":
|
||||
return []
|
||||
|
||||
# Apply filters to queryset
|
||||
if filters:
|
||||
queryset = queryset.filter(**filters)
|
||||
|
||||
# Prefetch related
|
||||
if prefetch_related:
|
||||
for prefetch in prefetch_related:
|
||||
queryset = queryset.prefetch_related(prefetch)
|
||||
|
||||
# Search
|
||||
return self._search(queryset, query_string, fields=fields)
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ from django.db import models
|
|||
|
||||
from wagtail.wagtailsearch.backends.base import BaseSearch
|
||||
from wagtail.wagtailsearch.indexed import Indexed
|
||||
from wagtail.wagtailsearch.utils import normalise_query_string
|
||||
|
||||
|
||||
class DBSearch(BaseSearch):
|
||||
|
|
@ -27,26 +26,16 @@ class DBSearch(BaseSearch):
|
|||
def delete(self, obj):
|
||||
pass # Not needed
|
||||
|
||||
def search(self, query_string, model, fields=None, filters=None, prefetch_related=None):
|
||||
# Get fields
|
||||
if fields is None:
|
||||
fields = [field.field_name for field in model.get_searchable_search_fields()]
|
||||
|
||||
# Start with all objects
|
||||
query = model.objects.all()
|
||||
|
||||
# Apply filters
|
||||
if filters:
|
||||
query = query.filter(**filters)
|
||||
|
||||
def _search(self, queryset, query_string, fields=None):
|
||||
if query_string is not None:
|
||||
# Normalise query string
|
||||
query_string = normalise_query_string(query_string)
|
||||
# Get fields
|
||||
if fields is None:
|
||||
fields = [field.field_name for field in queryset.model.get_searchable_search_fields()]
|
||||
|
||||
# Get terms
|
||||
terms = query_string.split()
|
||||
if not terms:
|
||||
return model.objects.none()
|
||||
return queryset.model.objects.none()
|
||||
|
||||
# Filter by terms
|
||||
for term in terms:
|
||||
|
|
@ -54,21 +43,16 @@ class DBSearch(BaseSearch):
|
|||
for field_name in fields:
|
||||
# Check if the field exists (this will filter out indexed callables)
|
||||
try:
|
||||
model._meta.get_field_by_name(field_name)
|
||||
queryset.model._meta.get_field_by_name(field_name)
|
||||
except:
|
||||
continue
|
||||
|
||||
# Filter on this field
|
||||
term_query |= models.Q(**{'%s__icontains' % field_name: term})
|
||||
|
||||
query = query.filter(term_query)
|
||||
queryset = queryset.filter(term_query)
|
||||
|
||||
# Distinct
|
||||
query = query.distinct()
|
||||
queryset = queryset.distinct()
|
||||
|
||||
# Prefetch related
|
||||
if prefetch_related:
|
||||
for prefetch in prefetch_related:
|
||||
query = query.prefetch_related(prefetch)
|
||||
|
||||
return query
|
||||
return queryset
|
||||
|
|
|
|||
|
|
@ -3,14 +3,12 @@ from __future__ import absolute_import
|
|||
import json
|
||||
|
||||
from django.db import models
|
||||
from django.db.models.query import QuerySet
|
||||
|
||||
from elasticsearch import Elasticsearch, NotFoundError, RequestError
|
||||
from elasticsearch.helpers import bulk
|
||||
|
||||
from wagtail.wagtailsearch.backends.base import BaseSearch
|
||||
from wagtail.wagtailsearch.indexed import Indexed, SearchField, FilterField
|
||||
from wagtail.wagtailsearch.utils import normalise_query_string
|
||||
|
||||
|
||||
class ElasticSearchMapping(object):
|
||||
|
|
@ -576,35 +574,5 @@ class ElasticSearch(BaseSearch):
|
|||
except NotFoundError:
|
||||
pass # Document doesn't exist, ignore this exception
|
||||
|
||||
def search(self, query_string, model_or_queryset, fields=None, filters=None, prefetch_related=None):
|
||||
# Find model/queryset
|
||||
if isinstance(model_or_queryset, QuerySet):
|
||||
model = model_or_queryset.model
|
||||
queryset = model_or_queryset
|
||||
else:
|
||||
model = model_or_queryset
|
||||
queryset = model_or_queryset.objects.all()
|
||||
|
||||
# Model must be a descendant of Indexed and be a django model
|
||||
if not issubclass(model, Indexed) or not issubclass(model, models.Model):
|
||||
return []
|
||||
|
||||
# Normalise query string
|
||||
if query_string is not None:
|
||||
query_string = normalise_query_string(query_string)
|
||||
|
||||
# Check that theres still a query string after the clean up
|
||||
if query_string == "":
|
||||
return []
|
||||
|
||||
# Apply filters to queryset
|
||||
if filters:
|
||||
queryset = queryset.filter(**filters)
|
||||
|
||||
# Prefetch related
|
||||
if prefetch_related:
|
||||
for prefetch in prefetch_related:
|
||||
queryset = queryset.prefetch_related(prefetch)
|
||||
|
||||
# Return search results
|
||||
def _search(self, queryset, query_string, fields=None):
|
||||
return ElasticSearchResults(self, ElasticSearchQuery(queryset, query_string, fields=fields))
|
||||
|
|
|
|||
Loading…
Reference in a new issue