如何在mongodb中组合多个聚合查询
我想找到一种简单的方法,将3个评级组合在一起,用于mongoDB查询。具体来说,是否有某种方法可以将3个聚合调用组合在一起。例如,我有以下数据。其中列出了电影的收视率,无论是imbd.rating、tomato.rating还是metacritic,我想找出每一个收视率的前两部电影。最下面的查询是如何根据tomato.rating获取前2个结果 资料 西红柿如何在mongodb中组合多个聚合查询,mongodb,aggregation-framework,Mongodb,Aggregation Framework,我想找到一种简单的方法,将3个评级组合在一起,用于mongoDB查询。具体来说,是否有某种方法可以将3个聚合调用组合在一起。例如,我有以下数据。其中列出了电影的收视率,无论是imbd.rating、tomato.rating还是metacritic,我想找出每一个收视率的前两部电影。最下面的查询是如何根据tomato.rating获取前2个结果 资料 西红柿 db.MovieData.aggregate([ { "$unwind": "$tomato" },
db.MovieData.aggregate([
{ "$unwind": "$tomato" },
{ "$sort": { "tomato.meter": -1 } },
{ "$limit": 2 },
{"$project": {title:1, "tomato.meter":1}},
])
嵌入
元批评家
db.MovieData.aggregate([
{ "$sort": { "metacritic": -1 } },
{ "$limit": 2 },
{"$project": {title:1, "metacritic":1}},
])
这些“有限”操作非常适合:
从问题中的数据返回:
{
"tomato" : [
{
"_id" : ObjectId("5c80979542dd84d91e5547d9"),
"title" : "Once Upon a Time in the West",
"tomato" : {
"meter" : 98
}
},
{
"_id" : ObjectId("5c80979542dd84d91e5547dd"),
"title" : "Slow West",
"tomato" : {
"meter" : 92
}
}
],
"imdb" : [
{
"_id" : ObjectId("5c80979542dd84d91e5547d9"),
"title" : "Once Upon a Time in the West",
"imdb" : {
"rating" : 8.6
}
},
{
"_id" : ObjectId("5c80979542dd84d91e5547dc"),
"title" : "West Side Story",
"imdb" : {
"rating" : 7.6
}
}
],
"metacrtic" : [
{
"_id" : ObjectId("5c80979542dd84d91e5547d9"),
"title" : "Once Upon a Time in the West",
"metacritic" : 80
},
{
"_id" : ObjectId("5c80979542dd84d91e5547dd"),
"title" : "Slow West",
"metacritic" : 72
}
]
}
只要有管道,这样运行多条管道是完全可以的
如果结果很大,最好运行独立的查询,最好是并行运行(例如在NodeJS的Promise.all()
下)并合并结果(如Promise.all()
示例所示)
虽然这实际上需要更多的数据库连接,但并行处理通常会抵消额外的开销。当然,这意味着组合结果(特别是从游标处理时)不会导致响应上的错误被破坏
注意:tomato
是一个对象
而不是数组
,因此您不使用$unwind
如果结果很大,比如说超过2000,你会推荐另一种方法吗?同样有趣的是,如果我把限制设置在2以上,我只会在IMBD对象中得到一个numberprint(9),而这就是我在metacritic对象中得到的所有结果。@chris添加了额外的解释以及我从你问题中的数据中得到的输出。
db.MovieData.aggregate([
{ "$sort": { "metacritic": -1 } },
{ "$limit": 2 },
{"$project": {title:1, "metacritic":1}},
])
db.MovieData.aggregate([
{ "$facet": {
"tomato": [
{ "$sort": { "tomato.meter": -1 } },
{ "$limit": 2 },
{"$project": {title:1, "tomato.meter":1}},
],
"imdb": [
{ "$sort": { "imdb.rating": -1 } },
{ "$limit": 2 },
{"$project": {title:1, "imdb.rating":1}},
],
"metacrtic": [
{ "$sort": { "metacritic": -1 } },
{ "$limit": 2 },
{"$project": {title:1, "metacritic":1}},
]
}}
])
{
"tomato" : [
{
"_id" : ObjectId("5c80979542dd84d91e5547d9"),
"title" : "Once Upon a Time in the West",
"tomato" : {
"meter" : 98
}
},
{
"_id" : ObjectId("5c80979542dd84d91e5547dd"),
"title" : "Slow West",
"tomato" : {
"meter" : 92
}
}
],
"imdb" : [
{
"_id" : ObjectId("5c80979542dd84d91e5547d9"),
"title" : "Once Upon a Time in the West",
"imdb" : {
"rating" : 8.6
}
},
{
"_id" : ObjectId("5c80979542dd84d91e5547dc"),
"title" : "West Side Story",
"imdb" : {
"rating" : 7.6
}
}
],
"metacrtic" : [
{
"_id" : ObjectId("5c80979542dd84d91e5547d9"),
"title" : "Once Upon a Time in the West",
"metacritic" : 80
},
{
"_id" : ObjectId("5c80979542dd84d91e5547dd"),
"title" : "Slow West",
"metacritic" : 72
}
]
}