【问题标题】:MongoDB aggregate: multiple group + elements arrayMongoDB聚合:多组+元素数组
【发布时间】:2017-03-12 07:30:49
【问题描述】:

文档的结构如下所示:

"_id" : ObjectId("581496e8564627c098e41755"),
"startdate": somedate,
"enddate": somedate,
"userId" : 1,
"activity" : "activity1",
"measures" : [ 
    {
        "M1" : 99,
        "M2" : 103,
        "M3" : 118,
        "M4" : 4
    }, 
    {
        "M1" : 136,
        "M2" : 89,
        "M3" : 108,
        "M4" : 6
    }, 

...等等

有 50 个用户,8 种活动,每个活动大约 100 个措施。用户可以在另一个日期使用其他度量进行相同的活动。 我在数据库中有大约 3000 个文档:每个用户每个用户 1 个文档,每个活动都有措施。

我想获得每个用户、每个活动的所有措施。

我有以下代码:

`db.armband.aggregate([
  {$match: { "measures.M1": { $gt: 1 } } },
  {$project: { _id: 0, userId: 1, activity:1, measures:1 } },
  {$sort: {userId:1, activity:1} },
  {$out: "actPerUser"}
  ])
` 

这里的问题是我每个活动都得到 1 个文档,并且按顺序执行了这些措施。但我明白了:

  • 1 个文档,用户 ID1,活动 1,度量 100
  • 1 个文档,用户 ID1,活动 1,度量 100
  • 1 个文档,用户 ID2,活动 1,度量 100

我想要一份文件: userid1、activity1、measures(该活动的所有度量值 - 在上面的示例中为 200。)

然后我试过了:

`db.armband.aggregate(
   [
     {
      $group:
     {
      _id: { userId: "$userId" },
       actMes: { $push:  { activity:"$activity", measures:   "$measures"     }     }
     }
   },
   {$project: { _id: 0, userId: "$_id.userId", actMes:1 } },
   {$sort: { userId:1}},     
 ]

)

这为每个用户提供了 1 个文档,其中包含不同的活动+措施(但仍然是双重活动)。

然后我尝试放松措施:

  `db.armband.aggregate(
    [
     {$unwind: '$measures'},
     {$group: {
     _id: { userId: "$userId" },
    activity: { $addToSet: "$activity" },
    measures: {$addToSet: "$measures"}
         }
       },
     { $sort: {userId:1}}
    ])
  `

这为每个用户提供了 1 个文档,其中包含 8 个活动,测量值约为 5900。

所以我有点迷茫,我怎样才能实现我想要的?是否有可能,1 个用户的 1 个文档,1 个活动,该活动的所有措施?

【问题讨论】:

    标签: mongodb mongodb-query aggregation-framework robo3t


    【解决方案1】:

    你可以使用:

    • 1 $unwind 删除数组
    • 1 $group 按活动/用户 ID 分组,$push 测量到新创建的数组中

    查询是:

    db.armband.aggregate([{
        "$unwind": "$measures"
    }, {
        $group: {
            _id: {
                userId: "$userId",
                activity: "$activity"
            },
            measures: { $push: "$measures" }
        }
    }])
    

    这给出了类似的东西:

    { "_id" : { "userId" : 2, "activity" : "activity1" }, "measures" : [ { "M1" : 99, "M2" : 103, "M3" : 118, "M4" : 4 }, { "M1" : 136, "M2" : 89, "M3" : 108, "M4" : 6 } ] }
    { "_id" : { "userId" : 2, "activity" : "activity2" }, "measures" : [ { "M1" : 99, "M2" : 103, "M3" : 118, "M4" : 4 }, { "M1" : 136, "M2" : 89, "M3" : 108, "M4" : 6 } ] }
    { "_id" : { "userId" : 1, "activity" : "activity1" }, "measures" : [ { "M1" : 99, "M2" : 103, "M3" : 118, "M4" : 4 }, { "M1" : 136, "M2" : 89, "M3" : 108, "M4" : 6 }, { "M1" : 99, "M2" : 103, "M3" : 118, "M4" : 4 }, { "M1" : 136, "M2" : 89, "M3" : 108, "M4" : 6 } ] }
    

    【讨论】:

    • 谢谢,就是这样。我首先想到的是,在执行代码时,我只能为每个用户的 1 个活动获得 50 个文档。但这是 Robomongo 的一个问题。当我将它写入一个新集合($out)时,我确实得到了所有文档,每个用户 1 个,每个活动以及该活动的所有度量。再次感谢!
    猜你喜欢
    • 2022-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-18
    • 2020-09-10
    • 2019-03-14
    • 2019-10-27
    • 2019-02-02
    相关资源
    最近更新 更多