所需的MySQL查询:
SELECT
*
FROM
myTable
WHERE
(
JSON_CONTAINS(access,'"a"','$.owner') OR
JSON_CONTAINS(access,'"b"','$.owner')
) AND
(
JSON_CONTAINS(access,'"c"','$.moderator') OR
JSON_CONTAINS(access,'"d"','$.moderator')
)
动态构建过滤器的一些逻辑片段:
const args = {x: ["a", "b"], y: ["c", "d"]}
let where = {}
// more code
if (args.x && Array.isArray(args.x)) {
const orWhere = args.x.map(x => sequelize.fn('JSON_CONTAINS', sequelize.col('access'), `"${x}"`,'$.owner'))
where = {
...where,
[Op.or]: orWhere
}
}
if (args.y && Array.isArray(args.y)) {
const orWhere = args.y.map(y => sequelize.fn('JSON_CONTAINS', sequelize.col('access'), `"${y}"`,'$.moderator'))
where = {
...where,
[Op.or]: orWhere
}
}
// more code
db.contacts.findAll({where})
这样做的问题是
args.x
和
args.y
[Op.or]: orWhere
from第二个语句重写where对象中已有的内容。
我已经通读了
Sequelize WHERE docs
,但尚未找到解决方案。如果我不做复杂的JSON查询函数,这会很简单。
注意
:是的,我正在阻止注入,但为了缩短代码,故意省略了该部分
编辑:
正如@Anatoly建议的,使用续集.fn而不是文字,但留下了相同的覆盖条件
where[Op.or]
在第二个if条件下