如何在mongodb中组合多个聚合查询

如何在mongodb中组合多个聚合查询,mongodb,aggregation-framework,Mongodb,Aggregation Framework,我想找到一种简单的方法,将3个评级组合在一起,用于mongoDB查询。具体来说,是否有某种方法可以将3个聚合调用组合在一起。例如,我有以下数据。其中列出了电影的收视率,无论是imbd.rating、tomato.rating还是metacritic,我想找出每一个收视率的前两部电影。最下面的查询是如何根据tomato.rating获取前2个结果 资料 西红柿 db.MovieData.aggregate([ { "$unwind": "$tomato" },

我想找到一种简单的方法,将3个评级组合在一起,用于mongoDB查询。具体来说,是否有某种方法可以将3个聚合调用组合在一起。例如,我有以下数据。其中列出了电影的收视率,无论是imbd.rating、tomato.rating还是metacritic,我想找出每一个收视率的前两部电影。最下面的查询是如何根据tomato.rating获取前2个结果

资料

西红柿

   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
                }
        ]
}