我想使用两个不同的查询检索至少出演过 5 部电影的演员列表。 在第一个查询中,未使用 $unwind,但在 $group 阶段中,它匹配每个演员的详细信息。此查询旨在收集和计算参与者而不破坏参与者数组。
在第二个查询中,$unwind 用于将表解构为单独的对象,使我们能够分析各个参与者。虽然最终目标是获取参加过至少 5 部电影的演员列表(对象表),但 $unwind 的使用使第二个查询略有不同。
第一个请求
db.films.aggregate([
{
$unwind:'$actors'
},
{
$group: {
_id: {
prenom:'$actors.first_name',
nom:'$actors.last_name'
},
nbr_films: {
$sum: 1
}
}
},
{
$match: {
nbr_films:{$gte:5}
}
},
{
$project: {
_id:0,
nom:"$_id.nom",
nbr_films:1
}
}
]);
返回:
[
{
"nbr_films": 6,
"nom": "Willis"
},
{
"nbr_films": 5,
"nom": "Oldman"
},
{
"nbr_films": 6,
"nom": "De Niro"
},
{
"nbr_films": 5,
"nom": "Caine"
},
{
"nbr_films": 6,
"nom": "Freeman"
}
]
第二个请求:
$group: {
_id: {
prenom:'$actors.first_name',
nom:'$actors.last_name'
},
nbr_films: {
$sum: 1
}
}
},
{
$match: {
nbr_films:{$gte:5}
}
},
{
$project: {
_id:0,
nom:"$_id.nom",
nbr_films:1
}
}
]); ```
**Returns:
**```
[
{
"nbr_films": 5
}
]
首先,我假设“actors”是一个数组,因为第一个查询在其上使用“$unwind”。
从查询的其余部分来看,actors 数组似乎包含一个文档数组,如
{first_name:"Bruce",last_name:"Willis"}
。
如果不展开,
$actors.first_name
将解析为一个数组,其中包含“actors”数组中 every对象的所有
first_name
值。
例如,如果文档如下所示:
{ "actors": [
{ "first_name": "Bruce", "last_name": "Willis" },
{ "first_name": "Gary", "last_name": "Oldman" },
{ "first_name": "Robert", "last_name": "De Niro" },
{ "first_name": "Michael", "last_name": "Caine" },
{ "first_name": "Morgan", "last_name": "Freeman" }
]}
然后
"$actors.first_name"
将解析为 ["Bruce", "Gary", "Robert", "Michael", "Morgan"]
示例
使用 $unwind 时,将从每个输入文档创建一组新文档,每个文档包含数组中的一个元素。 示例
在第一个查询中,演员数组在开始时展开,因此 $group 的 _id 包含单个演员的名字和姓氏,然后计数就是使用该演员的电影数量。
在第二个查询中,演员没有展开,因此 $group 的 _id 包含该电影中所有演员的名字数组和姓氏数组。计数将是使用相同演员且其名字在 actors
数组中以相同顺序出现的电影数量。