gpt4 book ai didi

django - Django Celery 任务中的 Elasticsearch 索引

转载 作者:行者123 更新时间:2023-12-03 01:18:54 24 4
gpt4 key购买 nike

我正在构建一个 Django Web 应用程序来存储文档及其相关元数据。

大部分元数据将存储在底层 MySQL 数据库中,在 Elasticsearch 中索引 OCR 的文档文本以启用全文搜索。我已合并 django-elasticsearch-dsl连接和同步我的数据模型,因为我还在索引(因此,双重存储)我的模型中的一些其他字段。我曾考虑使用 Haystack ,但它缺乏对最新 Elasticsearch 版本的支持。

当通过应用程序的管理界面上传文档时,post_save 信号会自动触发 Celery异步后台任务来执行 OCR,并最终将提取的文本索引到 Elasticsearch。

看到我的模型中没有定义全文字段(并希望避免这样做,因为我不想在数据库中存储或搜索 CLOB),我正在寻找更新的最佳实践我的 tasks.py 文件中的 Elasticsearch 文档。似乎没有办法使用 django-elasticseach-dsl 做到这一点(但也许我错了?)所以我想知道我是否应该这样做:

  • 尝试使用姐妹 django-elasticsearch-dsl-drf 通过 REST 与 Elasticsearch 交互包裹。
  • 通过使用更普通的 elasticsearch-dsl-py 更松散地将我的应用程序与 Elasticsearch 集成包(基于elasticsearch-py)。使用这种方法我会失去一些“奢侈”,因为我必须编写更多的集成代码,至少如果我想用信号连接我的模型。

  • 有最佳实践吗?还是我没有考虑过的另一种方法?

    更新 1:
    在尝试实现@Nielk 的答案时,我能够将 OCR 文本(下面的 tasks.py 中的结果 =“test”)持久化到 ElasticSearch 中,但它也保留在 MySQL 数据库中。我仍然对如何将 Submission.rawtext 配置为 ElasticSearch 的通路感到困惑。

    模型.py:
    class Submission(models.Model):

    rawtext = models.TextField(null=True, blank=True)
    ...
    def type_to_string(self):
    return ""

    文件.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(工作解决方案):

    模型.py
    类提交(模型。模型):
       @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

    文件.py
       @registry.register_document
    class SubmissionDocument(Document):

    rawtext = fields.TextField()

    def prepare_rawtext(self, instance):
    return instance.rawtext

    任务.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 -
    这就是我的意思:

    模型.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 - 修正代码错字

    关于django - Django Celery 任务中的 Elasticsearch 索引,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61282288/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com