文档包含对象数组的子文档,如果子文档为空,则不返回父文档

时间:2021-04-12 22:13:31

标签: node.js mongodb mongodb-query

下面是父文档的结构,我试图通过填充值沿着子文档获取父文档,但是当子文档历史数组为空时,结果返回空数组

{
  
    "resort" : ObjectId("5d52cd888bb76e30d8ef53f3"),
    "bookingAgent" : ObjectId("5f196af7117f7306a64bca05"),
    "leadId" : ObjectId("5fc39fe5a270851e6b5d7e78"),
    "contactAttempt" : ObjectId("604149ea7578a7001327b4ee"),
    "household" : ObjectId("5fc3a3f4a270851e6b7b118c"),
    "finalDisposition" : "No Show",
    "history" : []
}

在这个父文档中,作为对象数组的 history 具有以下架构

    history: [{
        tourDate: {
            type: Date,
            index: true
        },
        departureDate: Date,
        disposition: String,
        confirmationDispostion: String,
        confirmationDate: Date,
        dispositionReason: String,
        bookingImage: String,
        voucher: String,
        bookingAgent: {
          type: Schema.Types.ObjectId,
          refPath: 'staffs'
       },
      resort: {
       type: Schema.Types.ObjectId,
       refPath: 'Resort'
      }
    }]

我正在尝试查询

  BookingHistory.aggregate([
      { $match: { household: mongoose.Types.ObjectId(id) } },
      {
        $lookup: { 
          from: "staffs",
          localField: "bookingAgent",
          foreignField: "_id",
          as: "bookingAgent"
        }
      },
      {
        $lookup: { 
          from: "resorts",
          localField: "resort",
          foreignField: "_id",
          as: "resort"
        }
      },
      { $unwind: "$history"  },
      {
        $lookup: { 
          from: "resorts",
          localField: "history.resort",
          foreignField: "_id",
          as: "history.resort"
        }
      },
      {
        $lookup: { 
          from: "staffs",
          localField: "history.bookingAgent",
          foreignField: "_id",
          as: "history.bookingAgent"
        }
      },
      {$unwind: '$bookingAgent'},
      {$unwind: '$history.bookingAgent'},
      {$unwind: '$history.resort'},
      {$unwind: '$resort'},
      { '$group': {
        '_id': '$_id',
        'history': { '$push': '$history' },
        'parent': { '$first': '$$ROOT' },
      }}
    ]);

但如果子文档历史为空,则结果返回空数组

1 个答案:

答案 0 :(得分:0)

所以我必须将查询修改为此,$unwindpreserveNullAndEmptyArrays 财产

具有以下行为 可选。

  • 如果为 true,如果路径为空、缺失或空数组,则 $unwind 输出文档。
  • 如果为 false,如果 path 为空、缺失或空数组,则 $unwind 不会输出文档。

[
      { $match: { household: mongoose.Types.ObjectId(id) } },
      {
        $lookup: { 
          from: "staffs",
          localField: "bookingAgent",
          foreignField: "_id",
          as: "bookingAgent"
        }
      },
      {
        $lookup: { 
          from: "resorts",
          localField: "resort",
          foreignField: "_id",
          as: "resort"
        }
      },
      { 
        $unwind: {
          path: "$history",
          preserveNullAndEmptyArrays: true
        }
      },
      {
        $lookup: { 
          from: "resorts",
          localField: "history.resort",
          foreignField: "_id",
          as: "history.resort"
        }
      },
      {
        $lookup: { 
          from: "staffs",
          localField: "history.bookingAgent",
          foreignField: "_id",
          as: "history.bookingAgent"
        }
      },
      {
        $unwind: {
          path: '$bookingAgent',
          preserveNullAndEmptyArrays: true
        }
      },
      {
        $unwind: {
          path: '$history.bookingAgent',
          preserveNullAndEmptyArrays: true
        }
      },
      {  
        $unwind: {
          path: '$history.resort',
          preserveNullAndEmptyArrays: true
        },
      },
      { 
        $unwind: {
          path: '$resort',
          preserveNullAndEmptyArrays: true
        }
      },
      { '$group': {
        '_id': '$_id',
        'history': { '$push': '$history' },
        'parent': { '$first': '$$ROOT' },
      }}
    ];

https://docs.mongodb.com/manual/reference/operator/aggregation/unwind/