如何在mongodb中访问嵌套数组中的对象

时间:2013-01-08 14:55:34

标签: arrays mongodb nested

假设以下是投资组合集合:

{
    "_id" : ObjectId("50e5a858ad06fe3439000001"),
    "name" : "Portfolio 1",
    "description" : "description Portfolio 1",
    "userId" : "",
    "wallets" : [ ]
}
{
    "_id" : ObjectId("50e5a858ad06fe3439000002"),
    "name" : "Portfolio 2",
    "description" : "description Portfolio 2",
    "userId" : "",
    "wallets" : [
        {
            "_id" : ObjectId("50e5ac69f214a46139000001"),
            "name" : "wallet name 2-1",
            "description" : "description du wallet",
        "cards" : [
            {
                "_id" : ObjectId("50ebe4b5906a1e830d000001"),
                "name" : "Card 2-1-1",
                "description" : "description card 1",
            },
            {
                "_id" : ObjectId("50ebe61f2c0f189310000001"),
                "name" : "Card 2-1-2",
                "description" : "description de la carte",
            },
            {
                "_id" : ObjectId("50ebe6202c0f189310000002"),
                "name" : "Card 2-1-2",
                "description" : "description de la carte",
            },
            {
                "_id" : ObjectId("50ebe6212c0f189310000003"),
                "name" : "Card 2-1-3",
                "description" : "description de la carte",
            },
            {
                "_id" : ObjectId("50ebe6212c0f189310000004"),
                "name" : "Card 2-1-4",
                "description" : "description de la carte",
            }
        ]
    },
    {
        "_id" : ObjectId("50ebe6b22c0f189310000005"),
        "name" : "wallet 2-2",
        "description" : "",
        "cards" : [
            {
                "_id" : ObjectId("50ec21063f3c5f9f12000001"),
                "name" : "Card 2-2-1",
                "description" : "",
            }
        ]
    },
    {
        "_id" : ObjectId("50ebe6ba2c0f189310000006"),
        "name" : "wallet 2-3",
        "description" : "",
        "cards" : [
            {
                "_id" : ObjectId("50ec21233f3c5f9f12000002"),
                "name" : "Card 2-3-1",
                "description" : "",
            }
        ]
    }
]
}

我想通过投资组合,钱包和卡片_id来访问特定的卡片。 我想要的是:

{
"_id" : ObjectId("50e5a858ad06fe3439000002"),
"wallets" : [
    {
        "_id" : ObjectId("50e5ac69f214a46139000001"),
        "cards" : [
            {
                "_id" : ObjectId("50ebe4b5906a1e830d000001"),
                "name" : "Card 2-1-1",
                "description" : "description card 1",
            }
        ]
    },
]

}

我正在使用nodejs / mongo-native-driver上的mongodb 2.2.2。

任何帮助将不胜感激(shell示例或javascript赞赏)

谢谢你。

3 个答案:

答案 0 :(得分:3)

类似于使用Aggregation Framework的sle的回答,尽管最好提前从结果中剔除条目以防止不必要的展开。

    var aggOps = [
        { $match: {
            _id: portfolioID
        }},
        {$unwind: '$wallets'},
        { $match: {
            'wallets._id': walletID
        }},
        {$unwind: '$wallets.cards'},
        { $match: {
            'wallets.cards._id': cardID
        }},
    ];

    collection.aggregate(aggOps, function (err, result) {
        console.log(result);
    });

答案 1 :(得分:1)

  

http://docs.mongodb.org/manual/reference/projection/elemMatch/

根据mongodb文件,这可以通过$ elemMatch运营商来完成。我试图提出查询,你能检查它是否适用于你的情况,或者你可以根据你的需要进行修改。

var projection = { _id: 1, wallets: { _id: 'walletId', $elemMatch: { cards._id: 'cardId'}}};

db.portfolio.find(    {_id: 'portfolio_id'},    projection )

答案 2 :(得分:1)

可以使用Aggregation Framework。具体来说,$unwind运算符在这种情况下可能最有用。请记住$ unwind不会扩展空数组,因此示例中的第一个文档将从聚合管道中排除。

db.collection.aggregate(
    { $unwind : "$wallets" },
    { $unwind : "$wallets.cards" },
    { $match: {
        "_id"               : ObjectId("50e5a858ad06fe3439000002"),
        "wallets._id"       : ObjectId("50e5ac69f214a46139000001"),
        "wallets.cards._id" : ObjectId("50ebe4b5906a1e830d000001")
    } }
)