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

Mongoose多关联字段查询:筛选关联文档isActive为true的通知

方案1:基于现有populate逻辑改造(改动最小,易理解)

你可以在populate时添加match筛选条件,只拉取isActive: true的关联文档,不符合条件的关联字段会返回null,之后再过滤掉关联字段全为null的通知即可,同时要调整计数逻辑保证分页总数正确:

let totalItems;
const query = { organisationId: organisationId };

Notification.find(query)
  // populate时新增isActive筛选条件
  .populate({ path: "eventId", match: { isActive: true } })
  .populate({ path: "newsId", match: { isActive: true } })
  .populate({ path: "funeralNewsId", match: { isActive: true } })
  .lean()
  .then(allNotifications => {
    // 过滤出关联文档有效的通知
    const validNotifications = allNotifications.filter(item => {
      return item.eventId || item.newsId || item.funeralNewsId
    })
    totalItems = validNotifications.length
    // 分页+排序处理
    const paginatedNotifications = validNotifications
      .sort((a,b) => b.creationDate - a.creationDate)
      .slice(page * limit, (page + 1) * limit)
    res.status(200).json({ notifications: paginatedNotifications, totalItems })
  })
  .catch((err) => {
    next(err);
  });

提示:如果你的type字段取值和关联类型对应(比如type为event时仅eventId有值),可以把filter条件替换为对应type的判断,过滤效率更高。

方案2:使用聚合查询(性能更高,适合数据量大的场景)

直接通过MongoDB聚合的$lookup关联对应集合并做条件筛选,一次查询完成所有逻辑,避免内存中过滤的性能损耗:

const query = { organisationId: organisationId };

Notification.aggregate([
  { $match: query },
  // 关联Events集合,仅拉取isActive为true的文档
  {
    $lookup: {
      from: "events", // 此处为MongoDB集合的实际名称,一般是模型名小写加s,如有出入自行调整
      localField: "eventId",
      foreignField: "_id",
      pipeline: [{ $match: { isActive: true } }],
      as: "eventInfo"
    }
  },
  // 关联News集合
  {
    $lookup: {
      from: "news",
      localField: "newsId",
      foreignField: "_id",
      pipeline: [{ $match: { isActive: true } }],
      as: "newsInfo"
    }
  },
  // 关联FuneralNews集合
  {
    $lookup: {
      from: "funeralnews", // 此处确认集合实际名称
      localField: "funeralNewsId",
      foreignField: "_id",
      pipeline: [{ $match: { isActive: true } }],
      as: "funeralNewsInfo"
    }
  },
  // 过滤掉三个关联结果都为空的无效通知
  {
    $match: {
      $or: [
        { "eventInfo.0": { $exists: true } },
        { "newsInfo.0": { $exists: true } },
        { "funeralNewsInfo.0": { $exists: true } }
      ]
    }
  },
  // 排序、分页、计数统一处理
  { $sort: { creationDate: -1 } },
  {
    $facet: {
      totalItems: [{ $count: "count" }],
      notifications: [
        { $skip: page * limit },
        { $limit: limit },
        // 把关联数组转成对象,和之前populate的返回格式保持一致
        {
          $addFields: {
            eventId: { $first: "$eventInfo" },
            newsId: { $first: "$newsInfo" },
            funeralNewsId: { $first: "$funeralNewsInfo" }
          }
        },
        // 移除临时生成的关联字段
        { $unset: ["eventInfo", "newsInfo", "funeralNewsInfo"] }
      ]
    }
  },
  // 处理无匹配数据时的计数默认值
  {
    $addFields: {
      totalItems: { $ifNull: [{ $first: "$totalItems.count" }, 0] }
    }
  }
])
.then(result => {
  const { notifications, totalItems } = result[0]
  res.status(200).json({ notifications, totalItems })
})
.catch(err => next(err))

内容的提问来源于stack exchange,提问作者artsnr

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 14:57:04