You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 05:36:07