1

假设以下投资组合集合:

{
    "_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赞赏)

谢谢。

4

3 回答 3

3

类似于 slee 使用Aggregation Framework的答案,但最好尽早从结果中剔除条目以防止不必要的展开。

    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);
    });
于 2013-01-08T19:23:38.740 回答
1

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

db.collection.aggregate(
    { $unwind : "$wallets" },
    { $unwind : "$wallets.cards" },
    { $match: {
        "_id"               : ObjectId("50e5a858ad06fe3439000002"),
        "wallets._id"       : ObjectId("50e5ac69f214a46139000001"),
        "wallets.cards._id" : ObjectId("50ebe4b5906a1e830d000001")
    } }
)
于 2013-01-08T15:45:04.403 回答
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 )
于 2013-01-08T15:41:59.597 回答