查询 JSON 字段比较麻烦,有一下几种办法
- 若该字段是个JSON对象,用
字段 -> '$.json属性' = '某值'
进行查询 - 若该字段是个 JSON 数组,用 JSON_CONTAINS(字段, JSON_OBJECT('json属性', "内容"))
举例一张表
CREATE TABLE `template` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`code` varchar(50) NOT NULL DEFAULT ''
`principals` json DEFAULT NULL COMMENT '负责人',
`department` json DEFAULT NULL COMMENT '所属部门',
PRIMARY KEY (`id`),
) ENGINE=InnoDB CHARSET=utf8mb4;
principals 是个 json 数组
principals
[{"id": "2905688", "name": "杨三"}, {"id": "2904598", "name": "赵六"}]
[{"id": "2135687", "name": "卓七"}]
[{"id": "2546576", "name": "王五"}]
department 是个对象
department
{"id": 14250825, "name": "基础研发部"}
{"id": 14250826, "name": "金服事业部"}
查询对象
查询 department 为基础研发部的行
select * from template where department -> '$.name' = '基础研发部'
查询数组
查询 principals 里叫王五的
select * from template where JSON_CONTAINS(principals, JSON_OBJECT('name', '王五'))
用 sequelize 查询
const options = {
offset: page.offset,
limit: page.limit,
where: {
},
raw: true,
};
// JSON_CONTAINS mysqk 5.7 加入,可以查看文档
// https://dev.mysql.com/doc/refman/5.7/en/json-functions.html
options.where = {
[Op.and]: [
options.where,
Sequelize.fn(
'JSON_CONTAINS',
Sequelize.col('department'),
JSON.stringify({
id: parseInt(params.departmentId),
}),
),
Sequelize.fn(
'JSON_CONTAINS',
Sequelize.col('principals'),
JSON.stringify(condition)
),
],
};
return app.model.dbRr.template.findAndCountAll(options);
注意
JSON 字段是无法作为索引存在的,故而数据量若能到达百万级别,则千万别直接查这种 JSON 字段,查询的速度一定会很慢很慢。