如何限制/过滤子文档中的条目?

问题描述 投票:0回答:1

我已经快要得到我想要的了……但还差一点点。

我想要返回的是所有活动的狗舍,如果有任何狗舍有预订,则针对特定年份(2024),一组dayOfYear(例如[100,101,102,103])和一组房间(例如[1,2] ] )

这里是一个 Mongo 游乐场

这就是我现在得到的

[
        {
            "_id": "65ef79a2331ab6aef4fae5d4",
            "identifier": "1.1.6x10",
            "active": true,
            "partition": "1",
            "length": 10,
            "width": 6,
            "bookings": [
                {
                    "_id": "65ef88f444e7d6607498ac2e",
                    "year": 2024,
                    "dayOfYear": 100,
                    "duration": 6
                },
                {
                    "_id": "65f0ca69f2667460e600a46a",
                    "year": 2024,
                    "dayOfYear": 107,
                    "duration": 1
                }
            ]
        }
]

这就是我想要喜欢得到的 - 所有狗舍,并且标识符为“1.1.6x10”的狗舍应显示 2024 年 - 100 的单次预订,(为清楚起见 - 预订任何狗舍的预订2024 - 100 也应该返回,但对于此示例数据,只有 1.1.6x10 狗舍有预订)

[
        {
            "_id": "65ef79a2331ab6aef4fae5d4",
            "identifier": "1.1.6x10",
            "active": true,
            "partition": "1",
            "length": 10,
            "width": 6,
            "bookings": [
                {
                    "_id": "65ef88f444e7d6607498ac2e",
                    "year": 2024,
                    "dayOfYear": 100,
                    "duration": 6
                }
            ]
        },
        {
            "_id": "65ef79a2331ab6aef4fae5d5",
            "identifier": "1.2.6x10",
            "active": true,
            "partition": "2",
            "length": 10,
            "width": 6,
            "bookings": []
        },
        {
            "_id": "65ef79a3331ab6aef4fae5e5",
            "identifier": "2.1.4x10",
            "active": true,
            "partition": "1",
            "length": 10,
            "width": 4,
            "bookings": []
        },
        {
            "_id": "65ef79a3331ab6aef4fae5e6",
            "identifier": "2.2.4x10",
            "active": true,
            "partition": "2",
            "length": 10,
            "width": 4,
            "bookings": []
        },
        {
            "_id": "65ef79a3331ab6aef4fae5e7",
            "identifier": "2.3.4x10",
            "active": true,
            "partition": "3",
            "length": 10,
            "width": 4,
            "bookings": []
        }
    ]

这是我正在使用的 mongodb 管道,聚合在“kennels”上

  let pipeline = [
    {
      $lookup: {
        from: 'rooms',
        localField: 'REF_RoomID',
        foreignField: '_id',
        as: 'room',
      },
    },
    {
      $unwind: {
        path: '$room',
        preserveNullAndEmptyArrays: false,
      },
    },
    {
      $lookup: {
        from: 'bookings',
        localField: '_id',
        foreignField: 'REF_KennelID',
        as: 'bookings',
      },
    },
    {
      $match: {
        $and: [
          { active: true },
          { 'room.number': { $in: [1,2] } },
          //
          // this is my problem area
          //{ 'bookings.year': { $eq: 2024 } },
          //{ 'bookings.dayOfYear': { $eq: 100 } },
        ],
      },
    },
    {
      $project: {
        REF_RoomID: 0,
        room: 0,
        'bookings.REF_KennelID': 0,
        'bookings.__v': 0,
      },
    },
  ];

这是一些数据:

房间

{
  "_id":  "65ef799f331ab6aef4fae5ba",
  "number": "1",
  "length": "10",
  "width": "12"
},
{
  "_id": "65ef79a0331ab6aef4fae5be",
  "number": "2",
  "length": "10",
  "width": "12"
}

狗舍

{
  "_id": "65ef79a2331ab6aef4fae5d4",
  "REF_RoomID":  "65ef799f331ab6aef4fae5ba",
  "identifier": "1.1.6x10",
  "active": true,
  "partition": "1",
  "length": 10,
  "width": 6
},
{
  "_id": "65ef79a2331ab6aef4fae5d5",
  "REF_RoomID": "65ef799f331ab6aef4fae5ba",
  "identifier": "1.2.6x10",
  "active": true,
  "partition": "2",
  "length": 10,
  "width": 6
},
{
  "_id": "65ef79a3331ab6aef4fae5e5",
  "REF_RoomID": "65ef79a0331ab6aef4fae5be",
  "identifier": "2.1.4x10",
  "active": true,
  "partition": "1",
  "length": 10,
  "width": 4
},
{
  "_id": "65ef79a3331ab6aef4fae5e6",
  "REF_RoomID": "65ef79a0331ab6aef4fae5be",
  "identifier": "2.2.4x10",
  "active": true,
  "partition": "2",
  "length": 10,
  "width": 4
},
{
  "_id": "65ef79a3331ab6aef4fae5e7",
  "REF_RoomID": "65ef79a0331ab6aef4fae5be",
  "identifier": "2.3.4x10",
  "active": true,
  "partition": "3",
  "length": 10,
  "width": 4
}

预订

{
  "_id": "65ef88f444e7d6607498ac2e",
  "REF_KennelID": "65ef79a2331ab6aef4fae5d4",
  "year": 2024,
  "dayOfYear": 100,
  "duration": 6
},
{
  "_id": "65f0ca69f2667460e600a46a",
  "REF_KennelID": "65ef79a2331ab6aef4fae5d4",
  "year": 2024,
  "dayOfYear": 107,
  "duration": 1
}

谢谢你!

mongodb aggregation-framework pipeline subdocument
1个回答
0
投票
  1. 狗舍的

    $match
    阶段是
    active
    应该是您管道中的第一个。因此,不会对不匹配的狗窝执行查找,从而提高性能。

  2. 在第一个

    $lookup
    阶段,使用查找-
    pipeline
    ,而不是仅使用字段相等,然后匹配房间号。这是必要的,因为“我想返回的是所有活跃的狗舍”

    • 在当前形式中,任何没有房间“1”或“2”的活动狗窝根本不会显示在结果中。
  3. 第二个

    $lookup
    阶段也是如此 - 使用管道获取所有狗舍,无论它们是否有匹配的预订,甚至任何预订

db.kennels.aggregate([
  { $match: { active: true } },
  {
    $lookup: {
      from: "rooms",
      localField: "REF_RoomID",
      foreignField: "_id",
      pipeline: [
        {
          $match: {
            number: { $in: ["1", "2"] }
          }
        }
      ],
      as: "room"
    }
  },
  {
    $unwind: {
      path: "$room",
      preserveNullAndEmptyArrays: true
    }
  },
  {
    $lookup: {
      from: "bookings",
      localField: "_id",
      foreignField: "REF_KennelID",
      pipeline: [
        {
          $match: {
            year: 2024,
            dayOfYear: 100
          }
        }
      ],
      as: "bookings"
    }
  },
  {
    $unwind: {
      path: "$bookings",
      preserveNullAndEmptyArrays: true
    }
  },
  {
    $group: {
      _id: "$_id",
      identifier: { $first: "$identifier" },
      active: { $first: "$active" },
      partition: { $first: "$partition" },
      length: { $first: "$length" },
      width: { $first: "$width" },
      bookings: { $push: "$bookings" }
    }
  },
  {
    $project: {
      "bookings.REF_KennelID": 0,
      "bookings.__v": 0
    }
  }
])

蒙戈游乐场

您可能需要在

$sort
结束或之前有一些
$group
阶段。

© www.soinside.com 2019 - 2024. All rights reserved.