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

MongoDB聚合查询:lookup后筛选保留无匹配用户数据

MongoDB聚合查询调整方案

问题核心是避免$unwind导致的用户重复,同时保留所有初始筛选的用户,无匹配班次的用户显示shifts: {},有匹配的仅展示指定日期的班次数据。调整思路是将日期过滤逻辑嵌入$lookup的内部管道,而非后续的$match,再处理空数组的情况。

具体聚合表达式

db.users.aggregate([
  // 1. 初始用户筛选条件(替换为你的实际过滤规则)
  {
    $match: {
      // 示例:筛选状态为活跃的用户
      status: "active"
    }
  },
  // 2. 关联shifts集合,同时在内部管道过滤日期
  {
    $lookup: {
      from: "shifts",
      let: { user_id: "$_id" }, // 假设users的_id与shifts的userId字段关联
      pipeline: [
        {
          $match: {
            $expr: {
              $and: [
                { $eq: ["$userId", "$$user_id"] }, // 用户关联条件
                // 替换为你的日期匹配规则,示例:筛选2024年1月的班次
                { $gte: ["$date", ISODate("2024-01-01T00:00:00Z")] },
                { $lte: ["$date", ISODate("2024-01-31T23:59:59Z")] }
              ]
            }
          }
        }
      ],
      as: "shifts"
    }
  },
  // 3. 处理shifts字段:空数组转为空对象,非空则保留匹配的班次数据
  {
    $addFields: {
      shifts: {
        $cond: {
          if: { $eq: ["$shifts", []] },
          then: {},
          // 若希望仅展示单条匹配班次,可替换为 { $arrayElemAt: ["$shifts", 0] }
          else: "$shifts"
        }
      }
    }
  }
])

关键调整说明

  1. 将日期过滤移至$lookup内部:这样只会关联符合日期条件的班次,避免后续$unwind导致的用户重复,同时保留无匹配班次的用户(此时shifts为空数组)。
  2. 空数组转空对象:通过$cond判断shifts是否为空数组,为空则替换为{},满足需求格式。
  3. 避免$unwind:若无需拆分班次数组,直接保留数组即可;若仅需单条班次,用$arrayElemAt取数组第一个元素即可,无需$unwind。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 01:05:24