如何使用 Sequelize 访问 JSON 的属性

How to access properties of JSON with Sequelize

我有以下 JSON 用户结构:

{
        "userId": 3,
        "username": null,
        "email": "helpdesk@chronos.com.ar",
        "phoneNumber": null,
        "status": "active",
        "businessCompanyId": null,
        "roles": [
            {
                "userRolesId": 95,
                "userId": 3,
                "role": "helpdesk"
            }
        ]
    },

我正在尝试让所有用户使用 Sequelize,其中 'role' 属性 等于 'user' 或 'business':

app.get('/test', async (req, res) => {
  try {
    const response = await User.findAll({
      where: {
        roles: {
          [Op.or]: [
            { role: 'user' },
            { role: 'business' }
          ]
        }
      }
    });
    res.json(response);
    console.log(response);
  } catch (error) {
    console.log(error);
  }
});

但我在控制台收到以下错误:Error: Invalid value { role: 'user' }

知道如何使这个查询起作用吗?

很遗憾,答案取决于您的方言。你在用什么?邮政系统? MySQL ? ...?

无论如何,你有 2 个表之间的关系,对吧?用户和角色。

如果是,您将被迫尝试使用 sequelize.fn & sequelize.col 的解决方案。

例如,对于 Postgres,我这样做:

const response = await User.findAll({
  where: {
    [Op.or]: [
      db.sequelize.where(
        sequelize.fn('json_extract_path_text', db.sequelize.col('roles'), 'role'),
      Op.eq,
      'user'
      ),
      db.sequelize.where(
        sequelize.fn('json_extract_path_text', db.sequelize.col('roles'), 'role'),
      Op.eq,
      'business'
      )
    ]
  }
});

解释:

  • sequelize.where:生成一个有效参数,您可以将其用作 where 或 Op.and/Op.or。它的参数是:attribute, comparator, value
  • sequelize.fn:允许调用数据库函数(取决于您的方言)。它的参数是:function_name, param1, param2, param3, ...
  • sequelize.col: 允许从路径中获取列(支持简单列或预先加载)

由于roles是JSON字段,是数组,需要用JSON函数查找数组中的内容.

首先,JSON_EXTRACT提取数组内role的值(使用通配符提取所有角色)。

然后JSON_CONTAINS查找提取的角色是否包含“用户”或“业务”。

const response = await User.findAll({
    where: {
        [Op.or]: [
            Sequelize.fn('JSON_CONTAINS', 
                Sequelize.fn('JSON_EXTRACT', Sequelize.col('roles'), Sequelize.literal('"$[*].role"')), 
                '"user"'),
            Sequelize.fn('JSON_CONTAINS', 
                Sequelize.fn('JSON_EXTRACT', Sequelize.col('roles'), Sequelize.literal('"$[*].role"')), 
                '"business"')
        ]
    }
});