mysql - sequelize 嵌套包含 where 子句

标签 mysql node.js express sequelize.js

我正在使用 sequelize 进行一些过滤。

我当前的表结构:

  • 表 1 包含项目(有图像)和用户(不相关)
  • Table1 通过 Table1 上的 Table2id 与 Table2 有直接关系(而不是 Table3)
  • Table2 通过 Table2 上的 Table3id 与 Table3 有直接关系(而不是 Table4)
  • Table3 通过 Table3 上的 Table4id 与 Table4 有直接关系

考虑到我只能使用顶级 where 子句对 Table2 进行过滤,因此我也想对 Table3 和 Table4 进行过滤。

我填写 where 条件的方式只是使用一个基础对象:

var Table2id       = parseInt(req.query.Table2id) || null,
    Table3id       = parseInt(req.query.Table3id) || null,
    Table4id       = parseInt(req.query.Table4id) || null,
    whereCondition = { deleted: 0 }

if (Table2id) { whereCondition['table2id'] = Table2id }
if (Table3id) { whereCondition['table3id'] = Table3id }
if (Table4id) { whereCondition['table4id'] = Table4id }

Table1.findAndCountAll({
        limit: limit,
        offset: offset,
        order: 'created_at DESC',
        where: whereCondition,
        include: [
            {
                model: User,
            }, {
                model: Item,
                include: [
                    {
                        model: Image
                    }
                ]
            }, {
                model: Table2,
                include: [
                    {
                        model: Table3,
                        include: [
                            {
                                model: Table4,
                            }
                        ]
                    }
                ]
            }
        ],
}).then(function (results) { res.json(results) })

我尝试使用一些我发现的技巧,例如 whereCondition['$Table3.table3id$'] = Table3id 但无济于事。

如何过滤嵌套的包含?有没有另一种方法可以构造查询,这样我就不必嵌套包含,但仍保留此数据结构(是否有比我想到的更好的构造方法)?

编辑:所以我希望既能对包含的表进行排序,又能在顶级 where 子句中设置至少一个参数(如 deleted = 0)。

我试过如下修改查询:

var Table2id       = parseInt(req.query.Table2id) || null,
    Table3id       = parseInt(req.query.Table3id) || null,
    Table4id       = parseInt(req.query.Table4id) || null,
    whereCondition = { deleted: 0 },
    extraWhereCondition = {}

if (Table2id) { whereCondition['table2id'] = Table2id } // figured this can be left alone in this particular case (as it works in top-level where clause)
if (Table3id) { extraWhereCondition['table3id'] = Table3id }
if (Table4id) { extraWhereCondition['table4id'] = Table4id }

Table1.findAndCountAll({
        limit: limit,
        offset: offset,
        order: 'created_at DESC',
        where: whereCondition,
        include: [
            {
                model: User,
            }, {
                model: Item,
                include: [
                    {
                        model: Image
                    }
                ]
            }, {
                model: Table2,
                include: [
                    {
                        model: Table3,
                        where: extraWhereCondition,
                        include: [
                            {
                                model: Table4,
                                where: extraWhereCondition,
                            }
                        ]
                    }
                ]
            }
        ],
}).then(function (results) { res.json(results) })

但这给了我一个错误,即 Table2.Table3.Table4.table4id 在字段列表中是未知的。

最佳答案

你只需要将放在哪里,你也可以创建选项对象,然后将它传递给你需要的地方

  • 如果需要,在每个include中放入where condition
  • 需要真假改变加入规则

When an eager loaded model is filtered using include.where then include.required is implicitly set to true. This means that an inner join is done returning parent models with any matching children.

  • sequelize 将其称为 eager-loading 访问了解更多详情 eager-loading
var Table2 = require("../models/").table2; //and other model that u need

var option = {
  limit: limit,
  offset: offset,
  order: "created_at DESC",
  where: { deleted: 0 },
  include: [
    {
      model: User,
    },
    {
      model: Item,
      required: true,

      include: [
        {
          model: Image,
        },
      ],
    },
    {
      model: Table2,
      include: [
        {
          model: Table3,
          where: { deleted: 0 },
          include: [
            {
              model: Table4,
              where: { deleted: 0 },
            },
          ],
        },
      ],
    },
  ],
};

Table1.findAndCountAll(option).then(function (results) {
  res.json(results);
});

关于mysql - sequelize 嵌套包含 where 子句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43167937/

相关文章:

javascript - 如何使用 Node.js 创建自引用 MongoDB 模式并发布路由?

rest - 无法使用 Express API 发出 POST 或 GET 请求

mysql - 带有投影和列表的 Spring Data JPA 查询创建无效的 SQL

mysql - 从 3 个具有不同信息的表中获取数据

php - 如何在多选表单上回显数据库中多选的选定值

javascript - Socket.io 向房间广播在 socket.io v.0.9.13 中不起作用

python - 在nodejs中从python激活虚拟环境

javascript - Express 服务器未向客户端发送响应(使用 fetch)

mysql - 如何将一个表拆分为两个表并使用交叉链接 ID 链接记录

node.js - 强制 Browserify 转换依赖项?