【问题标题】:MongoDB: count the number of items in an arrayMongoDB:计算数组中的项目数
【发布时间】:2014-02-18 17:04:10
【问题描述】:

我有一个集合,其中集合中的每个文档都有一个名为 foo 的数组,其中包含一组嵌入文档。目前在 MongoDB shell 中是否有一种简单的方法来计算foo 中有多少实例?类似:

db.mycollection.foos.count()db.mycollection.foos.size()?

数组中的每个文档都需要有一个唯一的foo_id,我想快速计数,以确保集合中随机文档的数组中的元素数量正确。

【问题讨论】:

    标签: mongodb mongoid


    【解决方案1】:

    如果您使用的是最新版本的 mongo(2.2 及更高版本),则可以使用聚合框架。

    db.mycollection.aggregate([
      {$unwind: '$foo'},
      {$group: {_id: '$_id', 'sum': { $sum: 1}}},
      {$group: {_id: null, total_sum: {'$sum': '$sum'}}}
    ])
    

    这将为您提供您收藏的foos 总数。

    省略最后一个 group 将汇总每条记录的结果。

    【讨论】:

    • 太棒了,也帮助了我。您能否建议我如何在进一步计算中访问“total_sum”?
    【解决方案2】:

    在 MongoDB 2.6 中,聚合框架有一个新的数组 $size 可以使用:

    > db.mycollection.insert({'foo':[1,2,3,4]})
    > db.mycollection.insert({'foo':[5,6,7]})
    
    > db.mycollection.aggregate([{$project: { count: { $size:"$foo" }}}])
    { "_id" : ObjectId("5314b5c360477752b449eedf"), "count" : 4 }
    { "_id" : ObjectId("5314b5c860477752b449eee0"), "count" : 3 }
    

    【讨论】:

    • 在这种情况下有什么方法可以得到 7 (4+3) 吗?
    • @xxbidiao 当然,只需使用一个 $group 阶段来总结数组大小:db.mycollection.aggregate({$group: { _id: null, totalSize: { $sum: { $size: "$foo"}} }})
    • 我必须将[ ] 放在{$project: { count: { $size:"$foo" }}} 周围才能正常工作,请参阅github.com/Studio3T/robomongo/issues/…
    • @Max 我还建议寻找比 Robo3T 更积极更新的工具。每个 Robo3T 版本都嵌入了特定版本的 mongo shell,当与不匹配的 MongoDB 服务器版本(例如,显着较旧或较新)一起使用时,可能会导致意外问题。大多数管理工具使用 MongoDB API 来实现更广泛的跨版本兼容性。 MongoDB Compass 是免费的,由 MongoDB 团队提供支持,但根据您的要求,还有许多替代方案。
    • @datdinhquoc 您可以在聚合管道中添加初始 $match stage 以在应用投影之前过滤文档。如果没有任何其他阶段,此聚合查询将处理集合中的所有文档。现代版本的 MongoDB(3.4+)也有一个 $addFields stage,它可以用于创建输出,包括输入文档中的现有字段以及新添加的字段,如数组项的计数。
    【解决方案3】:

    使用投影和组

    db.mycollection.aggregate(
        [
            {
                $project: {
                    _id:0,
                    foo_count:{$size:"$foo"},
                }
            }, 
            {
                $group: {
                    foo_total:{$sum:"$foo_count"},
                }
            }
        ]
    )
    

    多个子数组计数也可以这样计算

    db.mycollection.aggregate(
        [
            {
                $project: {
                    _id:0,
                    foo1_count:{$size:"$foo1"},
                    foo2_count:{$size:"$foo2"},
                }
            }, 
            {
                $group: {
                    foo1_total:{$sum:"$foo1_count"},
                    foo2_total:{$sum:"$foo2_count"},
                }
            }
        ]
    )
    

    【讨论】:

    • 无论如何保护文档中缺少数组?
    猜你喜欢
    • 1970-01-01
    • 2017-11-19
    • 2018-12-13
    • 2021-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多