2012-01-20 32 views
0

我在PostgreSQL中有一個SQL查詢,我想將其轉換爲Django。如何將這個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變量定義感興趣,LIMIT在SQL。

如何翻譯的SQL查詢的Django ?我想Django的查詢是像我在這個意義上,它只返回例如100張單據,而不是1.000.000文件ID,然後100文件寫道手。

回答

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。

+0

謝謝你的回答,但這並不能幫助我。在SQL查詢中,它返回100個文檔。我不能限制內部查詢,我需要所有的IDS,然後獲取文檔。是否有可能用django寫入原始的sql? – Ali

+0

@Ali如果你只需要100個文件,你爲什麼需要所有的ID?正如我看到你不在外部查詢中做任何額外的排序,那麼這裏的限制點(而不是內部的)呢?並嘗試移動切片在我的答案外部查詢,我認爲它會得到你所需要的(雖然我仍然不明白爲什麼)。 – DrTyrsa

+0

你是對的,當我只需要100個文檔時,獲取所有這些ID是沒有意義的。 快速編輯:如何打印由Django生成的查詢? – Ali