NodeJS的Sequelize无法连接限制表

yur*_*com 11 sql node.js sequelize.js

我正在尝试实现一个看起来像这样的简单查询:

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
Run Code Online (Sandbox Code Playgroud)

非常简单:我希望得到连接结果然后限制为12.

在Sequelize中我使用以下功能:

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

但是这段代码会生成以下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
Run Code Online (Sandbox Code Playgroud)

它与我正在尝试的逻辑完全不同,因为在生成的sql中它首先获得任何12个结果,然后尝试与entity_area连接,当然随机12个结果不一定与entity_area匹配,所以我'没有得到任何结果.

请建议我一个正确的方法.属性表非常庞大,我必须使用"限制"而不是获取所有结果并在javascript中切片.此外,我不想开始使用原始查询.

yur*_*com 13

其实我自己找到了解决方案.我认为这是sequelize框架中的一个错误.
在node_modules/sequelize/lib/dialect/abstract/query_generator.js中有一个"selectQuery"函数,它包含以下行:

subQuery = limit && (options.hasIncludeWhere || options.hasIncludeRequired || options.hasMultiAssociation) && options.subQuery !== false
Run Code Online (Sandbox Code Playgroud)

首先,有一个选项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
})
Run Code Online (Sandbox Code Playgroud)

并且仍然有options.subQuery = undefined.

所以我不得不将query_generator.js中的函数更改为:

subQuery = limit && (options.hasIncludeWhere || options.hasIncludeRequired || options.hasMultiAssociation) && options.subQuery !== false && options.doSubQuery===true
Run Code Online (Sandbox Code Playgroud)

所以现在默认情况下它没有做这个丑陋的子查询,除非我明确指定doSubQuery:true.最后我得到了没有带有限制的子查询的正确查询.

  • https://github.com/sequelize/sequelize/blob/master/lib/dialects/abstract/query-generator.js#L876代码看起来有点不同,所以`options.subQuery = false`应该可以正常工作. (2认同)
  • @MickHansen这也解决了我的问题,但我有点担心,因为这不是Sequelize的文档.靠这个是安全的吗? (2认同)

小智 6

models.property.findAll(
{
    where: [...],
    include: [{...}],
    limit:12
},
{
    subQuery:false
})
Run Code Online (Sandbox Code Playgroud)

  • 此解决方案的一个问题是:如果任何关联模型与基本模型具有一对多关系,则返回的结果会较少。 (2认同)