如何将此SQL查询转换为Django?

时间:2012-01-20 07:18:14

标签: sql django django-orm

我在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。 1对多关系,令牌可以在很多文档中。

到目前为止,我有这个:

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,而我只对一小部分(由max_res变量和SQL中的LIMIT定义感兴趣。

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

1 个答案:

答案 0 :(得分:2)

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。