【问题标题】:How do I translate this SQL query to Django?如何将此 SQL 查询转换为 Django?
【发布时间】:2012-01-20 07:18:14
【问题描述】:

我在PostgreSQL 中有一个 SQL 查询,我想将它翻译成 Django。

select * from main_document 
where id in (
    select distinct on (document_id) document_id 
    from main_tokenindex 
    where token in('token1', 'token2')
    order by document_id, relevance desc
) LIMIT 100

我有 2 个表:Document 和 TokenIndex。一对多关系,一个token可以在多个文档中。

到目前为止我有这个:

terms = []
ids = [doc.document_id for doc in TokenIndex.objects.filter(token__in = terms).
      distinct('document__id').order_by("-relevance")]

list(Document.objects.filter(pk__in=ids))[:max_res]

如您所见,问题是我要去数据库获取 id 列表,然后再返回获取文档。这是低效的,因为我可能要处理数百万个文档 ID,而我只对一小部分感兴趣(由 SQL 中的 max_res 变量和 LIMIT 定义。

如何将 SQL 查询转换为 Django?我希望 Django 的查询与我手写的查询一样,例如它只返回 100 个文档,而不是 1.000.000 个文档 ID,然后是 100 个文档。

【问题讨论】:

    标签: sql django django-orm


    【解决方案1】:
    result = Document.objects.filter(pk__in=(TokenIndex.objects.filter(token__in=terms).distinct('document').order_by('document', '-relevance').values_list('document', flat=True)[:max_res]))
    

    如果您不想要 1.000.000 个文档 ID,只需返回 100,您需要在内部查询中使用 LIMIT,而不是在外部查询中。

    无论如何,我认为即使您将 LIMIT 与外部查询一起使用,它仍然会转换为您想要的 SQL。

    【讨论】:

    • 感谢您的回答,但这对我没有帮助。在 SQL 查询中,它返回 100 个文档。我无法限制我需要所有 IDS 然后获取文档的内部查询。是否可以用 django 编写原始 sql?
    • @Ali 如果您只需要 100 个文档,为什么还需要所有的 id?正如我所见,您在外部查询中没有做任何额外的排序,那么这里的限制点(而不是内部查询)是什么?并尝试在我对外部查询的回答中移动切片,我认为它会为您提供所需的东西(虽然我仍然不明白为什么)。
    • 你是对的,当我只需要 100 个文档时,获取所有这些 id 没有任何意义。快速编辑:如何打印 Django 生成的查询?
    • @Ali 你需要 100 个文档 = 你需要 100 个 ID。所以你需要限制内部查询。
    • 谁能解释一下(token__in=terms)。我是否正确理解 terms = [ ] 是一个空列表?如果是这样,空列表上的过滤器如何提供结果?
    猜你喜欢
    • 2023-01-31
    • 1970-01-01
    • 2019-10-31
    • 1970-01-01
    • 2021-05-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多