【发布时间】: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.2 和Postgres 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