首页 > 解决方案 > MongoDB在嵌套数组中按Id查找

问题描述

我的模型叫做Residence

{
    "_id": { "$oid": "5d88dfe45feb4c06a5cfb762" },
    "spaces": [{ 
        "_id": { "$oid": "5d88dfe45feb4c06a5cfb76f" },
        "name": "Building 2",
        "subSpace": [
            {
                "_id": { "$oid": "5d88dfe45feb4c06a5cfb771" },
                "name": "Basement"
            }, 
            {
                "_id": { "$oid": "5d88dfe45feb4c06a5cfb770" }, 
                "name": "Floors" // Get only the name by Id
            }
        ]
    }
}

按 Id查找spaceName (OK)

exports.getSpaceNameById = (spaceId) => {
    return Residence.find({ 'spaces._id': spaceId }, { _id: 0, spaces: { $elemMatch: { _id: spaceId } } })
}

现在我想要 Id 请求的子空间名称。

但我的梦想是同时拥有两者(按子空间 ID 查询,例如:5d88dfe45feb4c06a5cfb770):spaceName / subSpaceName只有 1 个请求。

谢谢你的帮助。


更新 1

我尝试这种方法,但响应是一个空数组

exports.getSubSpaceNameById = (spaceId) => {
    return Residence.aggregate([
        { $match: {'spaces.subSpace._id': spaceId}},
        { $project: {
            'spaces.subSpace': { $filter: {
                input: '$spaces.subSpace',
                as: 'mySubSpace',
                cond: { $eq: ['$$mySubSpace._id', spaceId]}
            }},
            _id: 0
        }}
    ])
}

标签: node.jsmongodbmongoose

解决方案


试试这个查询

   db.testers.aggregate([
    {
        $addFields:{
            "spaces":{
                $map:{
                    "input":"$spaces",
                    "as":"doc",
                    "in":{
                        $mergeObjects:[
                            "$$doc",
                            {
                                "subSpace":{
                                    $filter:{
                                        "input":"$$doc.subSpace",
                                        "as":"sn",
                                        "cond": {
                                        "$and": [
                                            { "$eq": [ "$$sn._id", "5d88dfe45feb4c06a5cfb770" ] },
                                        ]
                                    }

                                }
                            }
                            }
                        ]
                    }
                }
            }
        }
    }
]).pretty()

推荐阅读