【问题标题】:mongodb aggregation on big data, how to limit push in group?大数据上的mongodb聚合,如何限制组内推送?
【发布时间】:2020-08-05 04:03:03
【问题描述】:

我收集的数据: 任何名称都有样本价值:

{
    "name" : "kamal",
    "val" : 5
}
{
    "name" : "ali",
    "val" : 3
}
{
    "name" : "mohammad",
    "val" : 12
}
{
    "name" : "kamal",
    "val" : 6
}
{
    "name" : "kamal",
    "val" : 10
}
{
    "name" : "ali",
    "val" : 11
}
{
    "name" : "mohammad",
    "val" : 9
}
{
    "name" : "mohammad",
    "val" : 19
}
{    
    "name" : "ali",
    "val" : 6
}

我的收藏中有 20000000 个文档。 这一天增长了1000000 请帮我解决这个问题。 这个管道在 mongodb 工作:

db.test.aggregate([
    {$group:{
            _id:$name,
            vals:{$push:$val}
        }
    }
])

为任何名称添加所有 val,但在大数据内存限制中不起作用。 我需要这个: 我需要在组中限制推送数据数。

db.test.aggregate([
    {$group:{
            _id:$name,
            vals:{$push:$val , $limit:500000}
        }
    }
])

【问题讨论】:

  • $group 之前的$limit 阶段可以满足您的需要吗?
  • 这个集合中有多少个不同的namedb.test.distinct("name")?如果结果很小,我们可以定义$facet 阶段并手动限制每个管道..
  • 这限制了所有文件,但我需要对每个名称应用限制
  • 一千左右

标签: mongodb bigdata aggregate push limit


【解决方案1】:

当规模扩大时,没有什么神奇的解决方案可以让$group“快速”。

有几种处理规模的方法:

  1. 升级硬件,随着规模不断扩大,这显然不是很有效,您必须不断升级硬件才能跟上。但是在某些时候需要考虑。

  2. 更改架构:我不确定您的数据库是如何构建的,但在某些需求下,这确实可以加快某些查询,您的数据是否已分片?如果是这样,它是否正确分片?您可能可以进行许多更改来满足您的需求,但我还没有看到一个完美的设置架构,我想说没有什么可以改变来提高性能。

  3. 其中最简单的方法是使用预处理来准备数据。现在这是什么意思?这意味着我们创建了一个新的集合,它将是{name: string, vals: {val: number, count: number},现在每当您插入或更新您的一个文档时,您都必须更新这个集合,这会产生一些开销,但这是唯一有效的解决方案变化很大,而且有点容易实现。

【讨论】:

    【解决方案2】:

    不可能

    可能的解决方法 (MongoDB >= v3.6):此解决方案可能适合您,但性能很差。

    注意: 500.000 val/name 可能超过16MB limitation

    db.test.aggregate([
      {
        $group: {
          _id: "$name"
        }
      },
      {
        $lookup: {
          from: "test",
          let: {
            username: "$_id"
          },
          pipeline: [
            {
              $match: {
                $expr: {
                  $eq: [
                    "$$username",
                    "$name"
                  ]
                }
              }
            },
            {
              $project: {
                _id: 0,
                val: 1
              }
            },
            {
              $limit: 500000
            }
          ],
          as: "vals"
        }
      },
      {
        $project: {
          vals: {
            $map: {
              input: "$vals",
              in: "$$this.val"
            }
          }
        }
      }
    ],{allowDiskUse:true})
    

    MongoPlayground

    【讨论】:

      猜你喜欢
      • 2014-08-26
      • 1970-01-01
      • 2014-08-19
      • 1970-01-01
      • 2013-12-05
      • 1970-01-01
      • 2019-07-22
      • 2023-04-07
      相关资源
      最近更新 更多