2016-07-15 72 views
1

文献结构查询:组通过在嵌套的文件

COLLECTION: MyCollection的

{ 
    "_id" : ObjectId("578818ba8872933f6452c5b5"), 
    "user" : ObjectId("578818ba8872933f6452c5b5") , 
    "entries" : { 
     "items" : [ 
      { 
       "_id" : ObjectId("578819018872933f6452c5ba") 
       "date" : ISODate("2016-07-14T22:57:58.715Z"), 
       "values" : [ 
        { "type" : A, "value" : 4 }, 
        { "type" : B, "value" : 3 }, 
         ... 
       ] 
      }, 
      ... 
     ] 
    } 
} 

预期结果

  • 组由日期(日明智的,忽略该时间部分)
  • 平均值每种类型

    { 
        "_id" : "2016-07-14", 
        "values" : [ 
           { "type" : "A", "avgValue" : 3.2 }, 
           { "type" : "B", "avgValue" : 4.2 }, 
           ... 
           ] 
    } 
    

试过,但没有帮助

db.getCollection('myCollection').aggregate(
    [ 
     { 
      "$match" : { 
         "user" : ObjectId("578818ba8872933f6452c5b5") , 
         "entries.items.date" : {"$gte" : new ISODate("2016-07-11T00:00:00.715Z"),"$lt" : new ISODate("2016-07-18T00:00:00.715Z")} 
        } 
     }, 
     { "$unwind" : "entires.items"}, 
     { "$unwind" : "$entries.items.values"}, 
     { 
      "$group" : { "_id" : { '$year' : '$entries.items.date','$month' : '$entries.items.date','$day' : '$entries.items.date' }, 
          "values" : [{ "type": "$entries.items.values.type", 
              "avgValue" : { "$avg" : "$entries.items.values.value"} 
              } 
             ] 
         } 
     } 
    ] 
) 

什么是实现这一结果的正确方法是什么?

回答

1

可以使2组,一组用于计算每种类型的平均&日期,另一个用于通过日期推型&平均值阵列和组这些:

aggregate.js

var ret = db.device.aggregate(
    [{ 
     "$match": { 
      "user": ObjectId("578818ba8872933f6452c5b5"), 
      "entries.items.date": { 
       "$gte": new ISODate("2016-07-11T00:00:00.715Z"), 
       "$lt": new ISODate("2016-07-18T00:00:00.715Z") 
      } 
     } 
    }, { 
     "$unwind": "$entries.items" 
    }, { 
     "$unwind": "$entries.items.values" 
    }, { 
     $project: { 
      user: 1, 
      entries: 1, 
      day: { 
       year: { 
        $year: "$entries.items.date" 
       }, 
       month: { 
        $month: "$entries.items.date" 
       }, 
       day: { 
        $dayOfMonth: "$entries.items.date" 
       } 
      } 
     } 
    }, { 
     $project: { 
      user: 1, 
      entries: 1, 
      day: { 
       $concat: [{ 
         $substr: ["$day.year", 0, 4] 
        }, 
        "-", { 
         $substr: ["$day.month", 0, 2] 
        }, 
        "-", { 
         $substr: ["$day.day", 0, 2] 
        } 
       ] 
      } 
     } 
    }, { 
     $group: { 
      "_id": { 
       "date": "$day", 
       "type": "$entries.items.values.type" 
      }, 
      "avgValue": { 
       "$avg": "$entries.items.values.value" 
      } 
     } 
    }, { 
     $group: { 
      "_id": "$_id.date", 
      "values": { 
       "$push": { 
        "type": "$_id.type", 
        "avgValue": "$avgValue" 
       } 
      } 
     } 
    }] 
).toArray(); 

printjson(ret); 

测试:

mongo --quiet 127.0.0.1/yourDB aggregate.js 

我以前用过two projections分组,因为我没有得到您的分组_id我的系统上工作:

'$year' : '$entries.items.date','$month' : '$entries.items.date','$day' : '$entries.items.date' 

我不知道它来自我的蒙戈版本2.6

结果给出了这样的事情:

[ 
    { 
     "_id" : "2016-7-14", 
     "values" : [ 
      { 
       "type" : "B", 
       "avgValue" : 4.5 
      }, 
      { 
       "type" : "A", 
       "avgValue" : 6 
      } 
     ] 
    } 
] 
+0

虽然你的回答是有效的(这就是为什么我投了票并接受了它),但是可以避免一个分组和项目。 经过两次展开后,在表单id中使用日期和类型分组,虽然结果doc结构稍有不同,但结果仍然相同 –

+0

您是如何仅使用一个分组的?我没有看到你如何在一个分组字段中结合$ push&$ avg –