Я создаю веб-приложение Django для хранения документов и связанных с ними метаданных.
Большая часть метаданных будет храниться в базовой базе данных MySQL с текстом документа OCR. индексируется в Elasticsearch для включения полнотекстового поиска. Я включил django -elasticsearch-dsl для подключения и синхронизации своих моделей данных, так как я также индексирую (и, таким образом, дважды храню) несколько других полей, найденных в моих моделях. Я подумывал об использовании Haystack , но ему не хватает поддержки последних версий Elasticsearch.
Когда документ загружается через интерфейс администратора приложений, сигнал post_save автоматически вызывает Celery асинхронная фоновая задача для выполнения OCR и, в конечном итоге, индексирование извлеченного текста в Elasticsearch.
Видя, что в моей модели не определено полнотекстовое поле (и я надеюсь избежать этого, поскольку я не хочу сохранять или искать в базе данных CLOB), я ищу лучшую практику для обновления моих документов Elasticsearch из моего файла tasks.py. Кажется, не существует способа сделать это с помощью django -elasticseach-dsl (но, возможно, я ошибаюсь?), И поэтому мне интересно, должен ли я либо:
Попробуйте установить интерфейс с Elasticsearch через REST, используя сестринский пакет django -elasticsearch-dsl-drf .
Более свободно интегрировать мое приложение с Elasticsearch с помощью более ванильный пакет эластичный поиск-dsl-py (на основе эластичного поиска-py). Я бы потерял некоторую «роскошь» с этим подходом, поскольку мне пришлось бы написать немного больше кода интеграции, по крайней мере, если бы я хотел соединить свои модели с сигналами.
Is есть лучшая практика? Или другой подход, который я не рассмотрел?
Обновление 1: Пытаясь реализовать ответ от @Nielk, я могу сохранить текст распознавания (result = "test "в tasks.py ниже) в ElasticSearch, но он также сохраняется в базе данных MySQL. Я все еще не понимаю, как настроить Submission.rawtext как промежуточный элемент ElasticSearch.
models.py:
class Submission(models.Model):
rawtext = models.TextField(null=True, blank=True)
...
def type_to_string(self):
return ""
documents.py :
@registry.register_document
class SubmissionDocument(Document)
rawtext = fields.TextField(attr="type_to_string")
def prepare_rawtext(self, instance):
# self.rawtext = None
# instance.rawtext = "test"
return instance.rawtext
...
tasks.py (вызывается по сигналу post_save модели отправки):
@shared_task
def process_ocr(my_uuid)
result = "test" # will ultimately be OCR'd text
instance = Submission.objects.get(my_uuid=my_uuid)
instance.rawtext = result
instance.save()
Обновление 2 (рабочий раствор):
models.py Класс Представление (models.Model):
@property
def rawtext(self):
if getattr(self, '_rawtext_local_change', False):
return self._rawtext
if not self.pk:
return None
from .documents import SubmissionDocument
try:
return SubmissionDocument.get(id=self.pk)._rawtext
except:
return None
@rawtext.setter
def rawtext(self, value):
self._rawtext_local_change = True
self._rawtext = value
documents.py
@registry.register_document
class SubmissionDocument(Document):
rawtext = fields.TextField()
def prepare_rawtext(self, instance):
return instance.rawtext
tasks.py
@shared_task
def process_ocr(my_uuid)
result = "test" # will ultimately be OCR'd text
# note that you must do a save on property fields, can't do an update
instance = Submission.objects.get(my_uuid=my_uuid)
instance.rawtext = result
instance.save()