Node.js Sequelize 如何提取Postgres JSON字段内的指定属性
问题描述
我有一个Postgres数据库,数据结构如下图所示:
我希望查询数据时仅返回指定字段,目前编写的citizenController.js代码如下:
exports.getAllCitizen = async (req, res) => { const { page, size } = req.query; //Check if theres a NIK filter const nik = req.query.nik; const condition = nik ? { nik: { [Op.iLike]: `%${nik}%` } } : null; //Pagination const { limit, offset } = getPagination(page, size); try { const response = await Penduduk.findAndCountAll({ where: condition, attributes: ["id", "nik", "profil_penduduk"], limit, offset, }); const data = getPagingData(response, page, limit); return res.status(200).send(data); } catch (err) { console.log(err); } };
上述接口返回的响应结构如下图所示:
现在遇到的问题是:我不希望返回profil_penduduk对象的全部内容,只需要获取该对象内的nama、alamat、status_warga三个属性,对应结构如下图所示:
我尝试过直接修改attributes配置为以下写法,但是没有生效,请问该如何实现需求?
attributes: ["id", "nik", "profil_penduduk.nama","profil_penduduk.alamat","profil_penduduk.status_warga"]
解决方案
你尝试的写法不生效是因为Sequelize默认不会自动解析点语法提取JSON字段内部属性,根据你的profil_penduduk字段类型不同,对应解决方法如下:
情况1:profil_penduduk是Penduduk表的JSON/JSONB类型字段
方案A:数据库层面提取(推荐,减少数据传输)
使用Sequelize内置的json方法提取JSON内部字段,同时配置nest: true让返回结果自动解析成嵌套对象结构:
const response = await Penduduk.findAndCountAll({ where: condition, attributes: [ "id", "nik", [sequelize.json("profil_penduduk.nama"), "profil_penduduk.nama"], [sequelize.json("profil_penduduk.alamat"), "profil_penduduk.alamat"], [sequelize.json("profil_penduduk.status_warga"), "profil_penduduk.status_warga"] ], limit, offset, nest: true });
注意:上述代码里的sequelize是你初始化Sequelize连接的实例对象,需要先引入到当前文件
方案B:代码层面过滤(写法简单,兼容性好)
查询时保留原字段,拿到结果后手动裁剪profil_penduduk的属性:
try { const response = await Penduduk.findAndCountAll({ where: condition, attributes: ["id", "nik", "profil_penduduk"], limit, offset, raw: true // 直接返回普通JS对象,方便后续处理 }); // 过滤保留需要的字段 response.rows = response.rows.map(item => ({ ...item, profil_penduduk: { nama: item.profil_penduduk.nama, alamat: item.profil_penduduk.alamat, status_warga: item.profil_penduduk.status_warga } })); const data = getPagingData(response, page, limit); return res.status(200).send(data); } catch (err) { console.log(err); }
情况2:profil_penduduk是关联的独立模型
如果profil_penduduk是和Penduduk关联的另一张表,使用include配置指定关联表的返回字段即可:
const response = await Penduduk.findAndCountAll({ where: condition, attributes: ["id", "nik"], include: [{ model: ProfilPenduduk, // 替换为你实际定义的关联模型名 attributes: ["nama", "alamat", "status_warga"], required: true }], limit, offset, nest: true });
内容的提问来源于stack exchange,提问作者Bagus Amrullah Fikri
相关产品推荐
相关产品推荐

