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

如何在ExpressJS和MongoDB中过滤对象的子属性值?

如何在ExpressJS+MongoDB中过滤数组字段的子文档

需求:从MongoDB获取某代理的全部数据,仅保留testimonials数组中isDisplayed为true的条目。

原尝试代码

const getSingleAgent = expressAsync(async (req, res) => {
  const agent = await Agents.findOne({
    _id: req.params.id,
  });

  res.json(agent);

  } else {
    res.status(404);
    throw new Error("Agent not found.");
  }
});

实际返回结果

{
    "_id": "63ea901a85d4fbd62fb887b3",
    "name": "test namee",
    "isDeclined": false,
    "testimonials": [
        {
            "isDisplayed": true,
            "name": "test123123123123123",
        },
        {
            "isDisplayed": false,
            "name": "test123123123123123",
        },
        {
            "isDisplayed": false,
            "name": "test@gmail.com",
        },
    ],
}

期望返回结果

{
    "_id": "63ea901a85d4fbd62fb887b3",
    "name": "test namee",
    "isDeclined": false,
    "testimonials": [
        {
            "isDisplayed": true,
            "name": "test123123123123123",
        },
    ],
}

解决方案

方案1:MongoDB查询阶段过滤(推荐)

直接在数据库层面过滤数组,减少传输到服务器的数据量,适合大数据场景。可以用$filter操作符结合聚合管道或find的投影参数实现:

方式1:使用聚合管道
const getSingleAgent = expressAsync(async (req, res) => {
  const agent = await Agents.aggregate([
    // 匹配目标代理
    { $match: { _id: req.params.id } },
    // 投影并过滤testimonials数组
    {
      $project: {
        name: 1,
        isDeclined: 1,
        testimonials: {
          $filter: {
            input: "$testimonials",
            cond: { $eq: ["$$this.isDisplayed", true] }
          }
        }
      }
    }
  ]).then(result => result[0]); // 聚合返回数组,取第一个元素

  if (agent) {
    res.json(agent);
  } else {
    res.status(404);
    throw new Error("Agent not found.");
  }
});
方式2:使用find的投影参数(MongoDB 3.2+支持)
const getSingleAgent = expressAsync(async (req, res) => {
  const agent = await Agents.findOne(
    { _id: req.params.id },
    {
      name: 1,
      isDeclined: 1,
      testimonials: {
        $filter: {
          input: "$testimonials",
          cond: { $eq: ["$$this.isDisplayed", true] }
        }
      }
    }
  );

  if (agent) {
    res.json(agent);
  } else {
    res.status(404);
    throw new Error("Agent not found.");
  }
});

方案2:Node.js层面过滤(简单直接)

如果数据量不大,也可以在获取完整数据后,用数组的filter方法过滤:

const getSingleAgent = expressAsync(async (req, res) => {
  let agent = await Agents.findOne({ _id: req.params.id });

  if (agent) {
    // 过滤testimonials中isDisplayed为true的条目
    agent.testimonials = agent.testimonials.filter(item => item.isDisplayed === true);
    res.json(agent);
  } else {
    res.status(404);
    throw new Error("Agent not found.");
  }
});

内容的提问来源于stack exchange,提问作者Dave Spencer Bacay

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 23:25:27