小编典典

用NodeJS进行续集无法限制表的连接

sql

我正在尝试实现一个简单的查询,如下所示:

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中。我也不想开始使用原始查询。


阅读 172

收藏
2021-03-23

共1个答案

小编典典

实际上,我自己找到了解决方案。我认为这是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.

2021-03-23