|
10 | 10 | @file: elasticsearch_backend.py
|
11 | 11 | @time: 2019-04-13 11:46
|
12 | 12 | """
|
| 13 | + |
13 | 14 | import logging
|
14 | 15 | import re
|
15 |
| -import json |
16 |
| - |
17 |
| -from datetime import datetime, timedelta |
18 |
| - |
19 |
| -from django.conf import settings |
20 |
| -from django.core.exceptions import ImproperlyConfigured |
21 |
| -from django.utils import six |
22 |
| -from django.utils.datetime_safe import datetime |
23 | 16 | from django.utils.encoding import force_text
|
24 | 17 |
|
25 | 18 | from elasticsearch_dsl import Q
|
26 | 19 |
|
27 | 20 | from haystack.backends import BaseEngine, BaseSearchBackend, BaseSearchQuery, EmptyResults, log_query
|
28 |
| -from haystack.constants import DJANGO_CT, DJANGO_ID, ID |
29 |
| -from haystack.exceptions import MissingDependency, SearchBackendError, SkipDocument |
30 |
| -from haystack.inputs import Clean, Exact, PythonData, Raw |
31 | 21 | from haystack.models import SearchResult
|
32 | 22 | from haystack.utils import log as logging
|
33 |
| -from haystack.utils import get_identifier, get_model_ct |
34 |
| -from haystack.utils.app_loading import haystack_get_model |
35 |
| -from django_elasticsearch_dsl.registries import registry |
36 | 23 |
|
37 | 24 | from blog.models import Article
|
38 |
| -from blog.documents import ArticleDocument |
| 25 | +from blog.documents import ArticleDocument, ArticleDocumentManager |
39 | 26 |
|
40 | 27 | logger = logging.getLogger(__name__)
|
41 | 28 |
|
42 |
| -DATETIME_REGEX = re.compile( |
43 |
| - '^(?P<year>\d{4})-(?P<month>\d{2})-(?P<day>\d{2})T(?P<hour>\d{2}):(?P<minute>\d{2}):(?P<second>\d{2})(\.\d{3,6}Z?)?$') |
44 |
| - |
45 | 29 |
|
46 | 30 | class ElasticSearchBackend(BaseSearchBackend):
|
| 31 | + def __init__(self, connection_alias, **connection_options): |
| 32 | + super(ElasticSearchBackend, self).__init__(connection_alias, **connection_options) |
| 33 | + self.manager = ArticleDocumentManager() |
| 34 | + self._rebuild(None) |
47 | 35 |
|
48 |
| - def _get_models(self): |
49 |
| - models = registry.get_models() |
50 |
| - return set(models) |
| 36 | + def _get_models(self, iterable): |
| 37 | + models = iterable if iterable else Article.objects.all() |
| 38 | + docs = self.manager.convert_to_doc(models) |
| 39 | + return docs |
51 | 40 |
|
52 | 41 | def _create(self, models):
|
53 |
| - for index in registry.get_indices(models): |
54 |
| - index.create() |
55 |
| - |
56 |
| - def _populate(self, models): |
57 |
| - for doc in registry.get_documents(models): |
58 |
| - qs = doc().get_queryset() |
59 |
| - doc().update(qs) |
| 42 | + self.manager.create_index() |
| 43 | + docs = self._get_models(models) |
| 44 | + self.manager.rebuild(docs) |
60 | 45 |
|
61 | 46 | def _delete(self, models):
|
62 |
| - for index in registry.get_indices(models): |
63 |
| - index.delete(ignore=404) |
| 47 | + for m in models: |
| 48 | + m.delete() |
64 | 49 | return True
|
65 | 50 |
|
66 | 51 | def _rebuild(self, models):
|
67 |
| - if not self._delete(models): |
68 |
| - return |
69 |
| - |
70 |
| - self._create(models) |
71 |
| - self._populate(models) |
| 52 | + models = models if models else Article.objects.all() |
| 53 | + docs = self.manager.convert_to_doc(models) |
| 54 | + self.manager.update_docs(docs) |
72 | 55 |
|
73 | 56 | def update(self, index, iterable, commit=True):
|
74 |
| - models = self._get_models() |
75 |
| - # self._rebuild(models) |
| 57 | + models = self._get_models(iterable) |
| 58 | + self.manager.update_docs(models) |
76 | 59 |
|
77 | 60 | def remove(self, obj_or_string):
|
78 |
| - models = self._get_models() |
| 61 | + models = self._get_models([obj_or_string]) |
79 | 62 | self._delete(models)
|
80 | 63 |
|
81 | 64 | def clear(self, models=None, commit=True):
|
@@ -124,66 +107,6 @@ def search(self, query_string, **kwargs):
|
124 | 107 | 'spelling_suggestion': spelling_suggestion,
|
125 | 108 | }
|
126 | 109 |
|
127 |
| - def _from_python(self, value): |
128 |
| - """ |
129 |
| - Converts Python values to a string for Whoosh. |
130 |
| -
|
131 |
| - Code courtesy of pysolr. |
132 |
| - """ |
133 |
| - if hasattr(value, 'strftime'): |
134 |
| - if not hasattr(value, 'hour'): |
135 |
| - value = datetime(value.year, value.month, value.day, 0, 0, 0) |
136 |
| - elif isinstance(value, bool): |
137 |
| - if value: |
138 |
| - value = 'true' |
139 |
| - else: |
140 |
| - value = 'false' |
141 |
| - elif isinstance(value, (list, tuple)): |
142 |
| - value = u','.join([force_text(v) for v in value]) |
143 |
| - elif isinstance(value, (six.integer_types, float)): |
144 |
| - # Leave it alone. |
145 |
| - pass |
146 |
| - else: |
147 |
| - value = force_text(value) |
148 |
| - return value |
149 |
| - |
150 |
| - def _to_python(self, value): |
151 |
| - """ |
152 |
| - Converts values from Whoosh to native Python values. |
153 |
| -
|
154 |
| - A port of the same method in pysolr, as they deal with data the same way. |
155 |
| - """ |
156 |
| - if value == 'true': |
157 |
| - return True |
158 |
| - elif value == 'false': |
159 |
| - return False |
160 |
| - |
161 |
| - if value and isinstance(value, six.string_types): |
162 |
| - possible_datetime = DATETIME_REGEX.search(value) |
163 |
| - |
164 |
| - if possible_datetime: |
165 |
| - date_values = possible_datetime.groupdict() |
166 |
| - |
167 |
| - for dk, dv in date_values.items(): |
168 |
| - date_values[dk] = int(dv) |
169 |
| - |
170 |
| - return datetime(date_values['year'], date_values['month'], date_values['day'], date_values['hour'], |
171 |
| - date_values['minute'], date_values['second']) |
172 |
| - |
173 |
| - try: |
174 |
| - # Attempt to use json to load the values. |
175 |
| - converted_value = json.loads(value) |
176 |
| - |
177 |
| - # Try to handle most built-in types. |
178 |
| - if isinstance(converted_value, (list, tuple, set, dict, six.integer_types, float, complex)): |
179 |
| - return converted_value |
180 |
| - except: |
181 |
| - # If it fails (SyntaxError or its ilk) or we don't trust it, |
182 |
| - # continue on. |
183 |
| - pass |
184 |
| - |
185 |
| - return value |
186 |
| - |
187 | 110 |
|
188 | 111 | class ElasticSearchQuery(BaseSearchQuery):
|
189 | 112 | def _convert_datetime(self, date):
|
|
0 commit comments