我正在构建Django网络应用程序来存储文档及其相关的元数据。
大部分元数据将存储在底层的MySQL数据库中,OCR的文档文本将在Elasticsearch中建立索引,以启用全文本搜索。我并入了django-elasticsearch-dsl以连接和同步我的数据模型,因为我还为模型中的其他一些字段建立了索引(并因此进行了双存储)。我曾考虑使用Haystack,但它不支持最新的Elasticsearch版本。
[通过应用程序的管理界面上传文档时,post_save信号会自动触发Celery异步后台任务来执行OCR,最终会将提取的文本编入Elasticsearch。
[鉴于我在模型中没有定义全文字段(并希望避免这样做,因为我不想在数据库中存储或搜索CLOB),我正在寻求最佳实践用于从我的task.py文件更新我的Elasticsearch文档。似乎没有办法使用django-elasticseach-dsl进行操作(但是也许我错了吗?),所以我想知道是否应该:
[尝试使用姐妹django-elasticsearch-dsl-drf包通过REST与Elasticsearch进行交互。
通过使用更原始的elasticsearch-dsl-py软件包(基于elasticsearch-py),将我的应用程序与Elasticsearch松散地集成在一起。这种方法会使我失去一些“奢华”,因为我不得不编写更多的集成代码,至少如果我想用信号连接模型。
是否有最佳做法?还是我没有考虑过的另一种方法?
更新1:在尝试实现@Nielk的答案时,我能够将OCR文本(下面的task.py中的结果=“ test”)保存在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(在提交模型后保存信号上调用):
@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类Submission(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()
您可以在链接到模型的文档定义中添加其他字段(请参见文档https://django-elasticsearch-dsl.readthedocs.io/en/latest/fields.html#using-different-attributes-for-model-fields中的字段'type_to_field',并将其与'prepare_xxx'方法结合使用,以在创建实例时将其初始化为空字符串,并更新为当前值)这样可以解决您的问题吗?
编辑1-这就是我的意思:
models.py
class Submission(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
return SubmissionDocument.get(meta__id=self.pk).rawtext
@property.setter
def rawtext(self, value):
self._rawtext_local_change = True
self._rawtext = value
编辑2-固定代码错字