【问题标题】:Mongodb: How to get the count of documents in different collections using one query?Mongodb:如何使用一个查询获取不同集合中的文档数?
【发布时间】:2020-05-12 04:35:59
【问题描述】:

如何使用一个查询获取不同集合中的文档数?

假设我有三个集合:1. 用户、2. 帖子、3. 聊天室。

我想创建一个返回的查询:

 the total number of users, total number of posts and total number of
 chatrooms

是否可以在一个 MongoDB 查询中执行此操作?解决方案是否使用聚合并不重要。任何可行的解决方案都会很棒。

【问题讨论】:

    标签: mongodb mongoose mongodb-query aggregation-framework


    【解决方案1】:

    您可以使用如下聚合来做到这一点:

    db.Users.aggregate([
        /** After this stage there will be only one document with one count field, till following `lookup` stage */
        {
          $count: "TotalUsers"
        },
        /** lookup on 'Posts' collection without any conditions & just count docs, After this stage there will be only one doc with two fields */
        {
          $lookup: {
            from: "Posts",
            pipeline: [ { $count: "TotalPosts" }],
            as: "posts"
          }
        },
        /** lookup on 'Chatrooms' collection without any conditions & just count docs, After this stage there will be only one doc with three fields */
        {
          $lookup: {
            from: "Chatrooms",
            pipeline: [ { $count: "TotalChatrooms" } ],
            as: "Chatrooms"
          }
        },
        /** Transform the fields as like we wanted,
         * if a collection is empty you won't see that particular field in response, easy to handle it in code */
        {
          $project: {
            TotalUsers: 1,
            TotalChatrooms: { $arrayElemAt: [ "$Chatrooms.TotalChatrooms", 0 ] },
            TotalPosts: { $arrayElemAt: [ "$posts.TotalPosts", 0 ] }
          }
        }
      ])
    

    测试: mongoplayground

    参考:aggregation-pipeline

    注意:这里我们使用了specify-multiple-join-conditions-with-lookup 舞台,没有任何条件,只使用了$count。我相信这个查询可能足够快。如果可能的话,我宁愿走一条可以在所有 3 个集合上并行执行 .count() 的路线。但是,如果您希望在一个查询中完成它,您可以使用上面的聚合管道,以防万一您想检查查询的性能,请尝试使用$explain

    【讨论】:

    • 您为什么更喜欢在所有 3 个集合上并行执行 count()?在我的应用程序中,我实际上有超过 3 个集合,我想计算他们的文档,如果它在性能方面更简单、更好,我不介意使用替代方法。并且通过执行计数,您的意思是我使用普通查询而不是聚合?
    • @YulePale :好的,如果此聚合适用于您的所有输入集合,那么一切正常,此查询将避免执行多个数据库调用!是的,我的意思是正常的.count(),但正如你所说,你有更多的集合可以依靠,而不仅仅是 3,然后试试这个聚合查询..
    猜你喜欢
    • 2021-09-23
    • 2016-11-26
    • 2019-02-22
    • 2018-05-30
    • 1970-01-01
    • 2021-06-29
    • 2016-11-22
    • 2016-12-15
    • 1970-01-01
    相关资源
    最近更新 更多