按子子文档过滤子文档

Filter sub documents by sub-sub document

想象一下,您有以下猫鼬模式:

mongoose.model('Team', mongoose.Schema(
{
 players : [{ 
    trikots : [{
        isNew : Boolean,
        color : String
    }]
 }]
})

我想查询我的数据以获取所有符合以下条件的球队

我开始使用 $elemMatch 作为 sub-subdocument,但他们仍然是假玩家。我必须使用 aggregate() 吗?又如何?

是的,使用 aggregation framework. Your aggregation pipeline will consist of a $match operator which becomes the initial stage. This filters the documents in the collection by the specified criteria. The next pipeline steps will be a couple of $uniwnd operators on both arrays, players and the nested players.trikots. After the $uniwnd , you will need another $match 完全可以实现,然后将解构的数组文档过滤到所需的标准,这将成为您的最终解决方案。

让我们通过在 mongo shell:

中的团队集合中插入具有上述架构的几个文档来演示这一点
db.team.insert([
{
    "players" : [ 
        {
            "trikots" : [ 
                {
                    "isNew" : true,
                    "color" : "red"
                }, 
                {
                    "isNew" : true,
                    "color" : "blue"
                }
            ]
        }, 
        {
            "trikots" : [ 
                {
                    "isNew" : false,
                    "color" : "red"
                }, 
                {
                    "isNew" : true,
                    "color" : "green"
                }
            ]
        }
    ]
},
{
    "players" : [ 
        {
            "trikots" : [ 
                {
                    "isNew" : false,
                    "color" : "red"
                }, 
                {
                    "isNew" : false,
                    "color" : "blue"
                }
            ]
        }
    ]
}
])

然后可以按如下方式实现上述聚合管道:

var pipeline = [
    {
        "$match": {
            "players.trikots.isNew": true,
            "players.trikots.color": "red"
        }
    },
    {
        "$unwind": "$players"
    },
    {
        "$unwind": "$players.trikots"
    },
    {
        "$match": {
            "players.trikots.isNew": true,
            "players.trikots.color": "red"
        }
    }
];
db.team.aggregate(pipeline);

输出:

/* 1 */
{
    "result" : [ 
        {
            "_id" : ObjectId("554bce9a2ba32ccf7f139bae"),
            "players" : {
                "trikots" : {
                    "isNew" : true,
                    "color" : "red"
                }
            }
        }
    ],
    "ok" : 1
}

您的 mongoose 聚合将类似于:

Team.aggregate(pipeline).exec(callback);

或使用 Mongoose aggregation pipeline builder 进行流畅的调用:

Team.aggregate()
    .match({"players.trikots.isNew": true,"players.trikots.color": "red"})
    .unwind("players")
    .unwind("players.trikots")
    .match({"players.trikots.isNew": true,"players.trikots.color": "red"}) 
    .exec(callback);