按子子文档过滤子文档
Filter sub documents by sub-sub document
想象一下,您有以下猫鼬模式:
mongoose.model('Team', mongoose.Schema(
{
players : [{
trikots : [{
isNew : Boolean,
color : String
}]
}]
})
我想查询我的数据以获取所有符合以下条件的球队
- 有三角裤{isNew : true, color : red}
- 只有 select 位玩家拥有三脚架 {isNew : true, color : red}
我开始使用 $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);
想象一下,您有以下猫鼬模式:
mongoose.model('Team', mongoose.Schema(
{
players : [{
trikots : [{
isNew : Boolean,
color : String
}]
}]
})
我想查询我的数据以获取所有符合以下条件的球队
- 有三角裤{isNew : true, color : red}
- 只有 select 位玩家拥有三脚架 {isNew : true, color : red}
我开始使用 $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);