MongoDB 获取总数,因为使用聚合的结果非常慢

Posted

技术标签:

【中文标题】MongoDB 获取总数,因为使用聚合的结果非常慢【英文标题】:MongoDB get total count as result using aggregate is very slow 【发布时间】:2018-03-20 13:03:41 【问题描述】:

我正在使用 Mongodb 3.2.0 和聚合查询来通过“itemId”获取不同的“userId”。在我的收藏中,我有超过 2000 万份文档。我收藏中的文档如下所示。


    itemId : ObjectId('59c0a50f6ca8a1545bf1d206'),
    regionId : ObjectId('59c11af56ca8a1545bb32665'),
    userId : ObjectId('59c3cd626ca8a12e70866b0c')
  ,
  
    itemId : ObjectId('59c0a50f6ca8a1545bf1d206'),
    regionId : ObjectId('59c11af56ca8a1545bb32665'),
    userId : ObjectId('59c3cd626ca8a12e70865678')
   

据此,使用“itemId”作为我的选择器,我正在计算集合中可用的总不同“userId”。我在我的收藏中使用以下配置作为索引。

db.items.endureIndex("itemId" : 1)
db.items.endureIndex("userId" : 1)

我的聚合查询是

db.items.aggregate([
     $match:  itemId:  $in: [ ObjectId('59c0a50f6ca8a1545bf1d206'),  ObjectId('59c0a50f6ca8a1545bf1d207')]   ,
     $group:  _id: "$userId",
     $group:  _id: null, count : $sum : 1
    ])

我也将“allowDiskUse”设为 true。

查询执行超过 20 秒并给出结果。有没有其他方法可以提高执行速度?

我正在通过 NodeJS 本地 mongodb 驱动程序执行。使用不同的查询失败并显示“超过 16 MB 限制”。所以,我更喜欢使用“聚合”查询。

作为结果,总共有 600 000 个唯一用户 ID 作为 (ObjectId)。集合中可用的文件总数为 8 397 727。

【问题讨论】:

【参考方案1】:

可以试试这个来区分userId并被itemId过滤

db.collectionName.distinct('userId', 
  itemId: $in: [ObjectId('59c0a50f6ca8a1545bf1d206'), ObjectId('59c0a50f6ca8a1545bf1d207')]
).length

【讨论】:

作为结果,总共有“600000”个唯一的userId作为(ObjectId)。 我不知道有多少 id 超过了 16MB 的限制,因为我没有处理超过数百万的数据。只有 ID 不应该超过 16MB 不确定,只返回唯一 ID 的长度 我检查了 601004 数据并使用了 distinct 查询,该查询在 robomongo @SooryaPrakash 中的 4 秒内返回了预期值 谢谢。我会再试一次。但是可能会出现内存问题,将 601004 数据作为数组从 mongodb 返回。对吗?

以上是关于MongoDB 获取总数,因为使用聚合的结果非常慢的主要内容,如果未能解决你的问题,请参考以下文章

MongoDB慢聚合时间

为啥我的 MongoDB 聚合查询这么慢

如何在 MongoDB 中对聚合查询结果进行分页并获得总文档数(Node.js + Mongoose)?

mongodb3 之单一用途聚合

使用 GraphQL Query 在与 mongoose 聚合后从 MongoDB 获取结果

mongodb聚合(转)