猫鼬聚合查找只给一个对象

时间:2020-04-07 15:11:46

标签: node.js mongodb mongoose

我的收藏夹中的示例文档:

react-router-dom

我正在使用以下聚合:

{
    _id: "5e88dba0cae7632fe49226db"
    dishes: (2) ["5e8850b9980477519800a928", "5e8c838ee0b3a44e3491d347"]
    name: "test"
    dateOfMenu: "2020-04-05T09:21:07.000Z"
    __v: 0
    createdAt: "2020-04-04T19:10:24.814Z"
    updatedAt: "2020-04-04T19:10:24.814Z"
}

问题在于,它总是仅返回Menu.aggregate([ { $match: { dateOfMenu: {"$gte": nextWeekDateSunday, "$lt": nextWeekDateFriday} } }, { $lookup: { from: 'dishes', localField: 'dishes', foreignField: '_id', as: 'dishes' } } ]) 列表中的第一行,而不是所有数组。

1 个答案:

答案 0 :(得分:0)

您必须在$unwind之前执行$lookup步骤,以将餐具阵列扩展为Menu个文档流

Menu.aggregate([
    {
        $match: { } // add your search object here
    },
    {
        $unwind: '$dishes' // unwind this dishes array to expand this array to a stream of Menu documents
    },
    {
        $lookup: {
            from: 'dishes',
            localField: 'dishes',
            foreignField: '_id',
            as: 'dish'
        }
    },
    {
        $unwind: '$dish' // this to convert the array of one object to be an object
    }
])

这将返回一个文档数组,每个文档将包含一个餐具数组,但是此数组将仅包含一个餐具对象,因此我们可以在$unwind之后再次使用$lookup进行转换只有一个对象组成的数组,我们现在可以将其命名为dishs而不是dishs

输出将是类似的

{
    _id: "5e88dba0cae7632fe49226db",
    dish: {
        _id: "5e8850b9980477519800a928",
        name: "Spagetti", // assuming the dish model has a name
        // all the other properties in the dish Model
    },
    name: "test",
    dateOfMenu: "2020-04-05T09:21:07.000Z",
    __v: 0,
    createdAt: "2020-04-04T19:10:24.814Z",
    updatedAt: "2020-04-04T19:10:24.814Z"
}
{
    _id: "5e88dba0cae7632fe49226db",
    dish: {
        _id: "5e8c838ee0b3a44e3491d347",
        mame: "Burger", // assuming the dish model has a name
        // all the other properties in the dish Model
    },
    name: "test",
    dateOfMenu: "2020-04-05T09:21:07.000Z",
    __v: 0,
    createdAt: "2020-04-04T19:10:24.814Z",
    updatedAt: "2020-04-04T19:10:24.814Z"
}

如果您需要对具有相同菜单ID的所有文档进行分组,因此您在同一文档中拥有菜单及其所有菜肴,我们可以使用$group

进行一些分组

所以查询将是这样

Menu.aggregate([
    {
        $match: { } // add your search object here
    },
    {
        $unwind: '$dishes' // unwind this dishes array to expand this array to a stream of Menu documents
    },
    {
        $lookup: {
            from: 'dishes',
            localField: 'dishes',
            foreignField: '_id',
            as: 'dish'
        }
    },
    {
        $unwind: '$dish' // this to convert the array of one object to be an object
    },
    {
        $group: {
            _id: '$_id', // the _id of the menu
            name: { $first: '$name' }, // name of the menu
            createdDate: { $first: '$createdDate' }, // createdDate of the menu
            dishes: { // dishes array in this menu
                $addToSet: '$dish' // here we used addToSet, as here we have an array of dishes, so push the dish to that array
            }
        }
    }
])

结果将是类似的

{
    "_id" : ObjectId("5e88dba0cae7632fe49226db"),
    "name" : "Test",
    "createdDate" : ISODate("2020-04-05T22:00:00Z"),
    "dishes" : [
        {
            "_id" : ObjectId("5e8850b9980477519800a928"),
            "name" : "Spaggetti",
            "main" : true
        },
        {
            "_id" : ObjectId("5e8c838ee0b3a44e3491d347"),
            "name" : "Burger",
            "main" : true
        }
    ]
}