【问题标题】:Django Query to Combine Multiple ArrayFields to one text stringDjango Query 将多个 ArrayFields 组合成一个文本字符串
【发布时间】:2021-08-12 03:00:52
【问题描述】:

我有一个对象模型,其中Documents 是可以具有Attachments 的长文本文件,并且两组对象也可以具有类似电子表格的Tables。每个表格都有一个带有文本的矩形阵列。我希望用户能够在表格内容中搜索关键字,但结果将由主文档显示(因此,您不会看到每个匹配的表格,而只会看到具有最多匹配表格的文档您的查询)。

您可以在下面看到我正在尝试运行的测试查询,它在理想情况下会将所有表格内容(跨所有附件)转换为一个长字符串,然后我可以将其传递给 SearchHighlight 以制作标题.出于某种原因,测试查询将表作为不同的对象返回,而不是连接到一个长字符串。 我正在使用模仿 Postgres 13 StringAgg 的自定义函数,因为我正在使用 Postgres 10。

提前感谢您的帮助,如果我需要提供更多信息来复制此内容,请告诉我。

我的models.py:

class Document(AbstractDocument):
  tables = GenericRelation(Table)

class Attachment(AbstractDocument):
  tables_new = GenericRelation(Table)  
  main_document = ForeignKey(Document, on_delete=CASCADE, related_name="attachments")

class Table(models.Model):
  content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
  object_id = models.SlugField()
  content_object = GenericForeignKey()

  content = ArrayField(ArrayField(models.TextField(null=True)))

我的查询:

def myStringAgg(field: str):
  return Func(
    F(field),
    Value(" "),
    Value(""),
    function="array_to_string",
    output_field=models.TextField(),
  )


s = Document.objects.all() \
  .annotate(tt=myStringAgg("attachments__tables__content")) \
  .values_list('tt', flat=True)
# what I get
>>> <DocumentSet ['table1', 'table2']>
# what I want
>>> <DocumentSet ['table1 table2']>

我正在使用Django 3.2Postgres 10

为了阐明我的全部范围是什么,最终查询的样子如下:

qs = Document.objects.filter(  
  Q(tables__search_vector=query) | 
  Q(attachments__tables__search_vector=query)
  )
  .annotate(rank=rank)
  .order_by("-rank")
  .annotate(snippet=SearchHeadline(
     myStringAgg("attachments__tables__content"),
   query, max_fragments=5)
)

【问题讨论】:

    标签: python django postgresql django-orm


    【解决方案1】:
    You can use the join function to create a string from a list:
    s = Document.objects.all() \
      .annotate(tt=myStringAgg("attachments__tables__content")) \
      .values_list('tt', flat=True)
    
    s = " ". join(list(s))
    

    【讨论】:

    • 这不起作用,因为我将结果字符串传递给进一步的 SQL 处理(进入 SearchHeadline 函数调用)。所以我需要连接发生在 SQL 查询中,而不是之后。
    猜你喜欢
    • 1970-01-01
    • 2018-10-01
    • 1970-01-01
    • 2013-12-25
    • 1970-01-01
    • 1970-01-01
    • 2019-03-22
    • 1970-01-01
    • 2011-04-30
    相关资源
    最近更新 更多