如何使用 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"')
]
}
});
我有以下 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"')
]
}
});