我正在尝试实现一个简单的查询,如下所示:
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中。我也不想开始使用原始查询。
实际上,我自己找到了解决方案。我认为这是sequelize框架中的错误。 在node_modules / sequelize / lib / dialect / abstract / query_generator.js中,有一个“ selectQuery”函数,其内容如下:
subQuery = limit && (options.hasIncludeWhere || options.hasIncludeRequired || options.hasMultiAssociation) && options.subQuery !== false
首先,有一个选项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 = undefined。
所以我不得不将query_generator.js中的函数更改为类似以下内容:
subQuery = limit && (options.hasIncludeWhere || options.hasIncludeRequired || options.hasMultiAssociation) && options.subQuery !== false && options.doSubQuery===true
So now by default it’s not doing this ugly subquery unless i specify explicitely doSubQuery:true. And finally i got the proper query without subquery with limit.