Answer is at bottom of my question

我就快得到我想要的了.但就是有点不对劲.

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

这是一张Mongo playground美元的钞票

这就是我现在得到的

[
        {
            "_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
                }
            ]
        }
]

这是我like要得到的-所有狗舍,AND标识符为"1.1.6x10"的狗舍应该显示2024-like年的单一预订,(for clarity - bookings for any Kennel with a booking on 2024 - 100 should also be returned, but for this example data, only the 1.1.6x10 kennel has a booking)

[
        {
            "_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,
      },
    },
  ];

以下是一些数据:

Rooms

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

Kennels

{
  "_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
}

Bookings

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

谢谢你!

ANSWER

这就是管用的管道--感谢https://stackoverflow.com/users/1431750/aneroid推动我走上正确的道路!

let pipeline = [
    {
      $match: {
        active: true,
      },
    },
    {
      $lookup: {
        from: "rooms",
        localField: "REF_RoomID",
        foreignField: "_id",
        as: "room",
      },
    },
    {
      $match: {
        "room.number": {
          $in: ["1","2"],
        },
      },
    },
    {
      $unwind: {
        path: "$room",
        preserveNullAndEmptyArrays: true,
      },
    },
    {
      $lookup: {
        from: "bookings",
        localField: "_id",
        foreignField: "REF_KennelID",
        pipeline: [
          {
            $match: {
              year: {
                $in: [2024],
              },
              dayOfYear: {
                $in: [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: {
        identifier: 1,
      },
    },
  ];

推荐答案

  1. 狗舍的$match阶段是active,应该是你的第一个阶段.因此,不会对不匹配的狗舍执行查找,这会提高性能.

  2. 在第一个$lookup阶段,use a lookup-pipeline而不是只有场相等,然后是房间号匹配.这是必要的,因为"I want to return is all active kennels".

    • 在当前的形式中,任何没有房间"1"或"2"的活动狗舍将根本不会显示在结果中.
  3. 第二个$lookup阶段也是如此-使用一个管道来获得所有的狗舍,无论它们是否有匹配的预订,甚至any bookings.

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
    }
  }
])

Mongo Playground

$group赛道的最后或之前,你可能需要大约$sort个赛段.

Mongodb相关问答推荐

使用mongosh将大型json文件插入到mongo集合中

Mongo DB-如果一个特定字段有多个文档匹配,则更新文档字段

筛选出嵌套数组中的记录Mongo DB聚合

如何用Python和MongoDB找到单据字段的最大值?

如何在 go mongo-driver 中为 options.FindOne() 设置限制

DB 中的引用对象在 GraphQL 查询中返回 null

通过 docker 运行的 MongoDB 服务器无法互相看到(名称解析中的临时故障)

使用 mongodb 时是否需要规范化数据库?

mongo.lock 文件有什么用?

MongoDB映射/减少多个集合?

Stripe:必须提供来源或客户

Mongodb插入没有_id字段的文档

django 和 mongodb 是否使迁移成为过go ?

如何在任意深度查找 MongoDB 字段名称

如何使用 java 驱动程序更新 mongo db 中的文档字段?

使用已排序的数据获取不同的值

Mongo:匹配聚合查询中的日期似乎被忽略了

如何在 $match 内的 mongodb 聚合查询中使用 $regex

是否可以使用聚合框架对 MongoDB 中的 2 个字段求和?

如何使用 Spring 的 MongoTemplate 和 Query 类检索字段子集?