2014-09-24 90 views
10

我想實現一個簡單的查詢應該是這樣的:Sequelize用的NodeJS不能加入表與限制

select * from property join entity_area on property.id=entity_area.entity_id and entity_area.area_id=1 where property.price>300000 limit 12 

很簡單:我想要得到的加入結果,然後以限制12.

在Sequelize我使用下列的函數:

return models.property.findAll(
{ 
    where: ["price>=?", 300000], 
    include: [ 
    { 
     model:models.entity_area, 
     where: { area_id:1 } 
    } 
    ], 
    limit:12 
}) 

但這代碼生成以下SQL:

select property.*, entity_area.* from (select * from property where property.price>300000 limit 12) join entity_area on property.id=entity_area.entity_id and entity_area.area_id=1 

它與我想要做的完全不同的邏輯,因爲在生成的sql中它首先得到任何12個結果,然後嘗試與entity_area結合,當然隨機12結果不一定匹配entity_area,所以我沒有得到任何結果。

請給我一個正確的做法。屬性表非常龐大,我必須使用「限制」而不是獲取所有結果並在javascript中對其進行切片。我也不想開始使用原始查詢。

回答

12

其實我自己找到了解決方案。我認爲這是後續框架中的一個錯誤。
在node_modules/sequelize/LIB /方言/抽象/ query_generator.js有一個「selectQuery」功能,其具有下面的行:

subQuery = limit && (options.hasIncludeWhere || options.hasIncludeRequired || options.hasMultiAssociation) && options.subQuery !== false 

首先有可能作爲傳遞一個選擇的子查詢假刪除子查詢生成。 Sequelize文檔對此沒有任何評價。但是,如果你在findAll對象中傳遞subQuery:false,它將不起作用,因爲它由於某種原因而變得與selectQuery函數一樣。
我想是這樣的:

return models.property.findAll(
{ 
    where: ["price>=?", 300000], 
    include: [ 
    { 
     model:models.entity_area, 
     where: { area_id:1 } 
    } 
    ], 
    limit:12, 
    subQuery:false 
}) 

,還是把options.subQuery =不確定。

,所以我不得不改變query_generator.js的功能是這樣的:

subQuery = limit && (options.hasIncludeWhere || options.hasIncludeRequired || options.hasMultiAssociation) && options.subQuery !== false && options.doSubQuery===true 

所以現在默認情況下它沒有做這個醜陋的子查詢,除非明確地我指定doSubQuery:真。最後,我得到了沒有限制的子查詢的正確查詢。

+2

https://github.com/sequelize/sequelize/blob/master/lib/dialects/abstract/query-generator.js#L876 代碼看起來有點不同,這些天所以'選項.subQuery = false'應該簡單地工作。 – 2015-05-21 05:34:41

+2

@MickHansen這也解決了我的問題,但我有點擔心,因爲這不在Sequelize的文檔中。依靠它可以安全嗎? – 2016-02-26 19:08:23

+0

很好的答案,它的工作,謝謝 – 2017-12-01 10:05:48

5
models.property.findAll(
{ 
    where: [...], 
    include: [{...}], 
    limit:12 
}, 
{ 
    subQuery:false 
}) 
+0

非常感謝!這是正確的答案。你爲我節省了很多工作 – Oxenarf 2017-05-04 13:31:18

0

我最近使用sequelize 4.28.6這個問題,這是對我工作

User.findAll(
{ 
    where: { 
    $Tasks$: null, 
    }, 
    include: [ 
    { 
     model: Task, 
     // required: false, 
    }, 
    ], 
    limit: 3, 
    subQuery: false, 
}) 

@yuriscom答案仍然有效,但是,我並沒有要編輯的代碼庫sequelize因爲問題有被修正和添加subQuery: false,工作