Mongodb 具有多个匹配或并集的Mongo聚合

Mongodb 具有多个匹配或并集的Mongo聚合,mongodb,aggregation-framework,union,Mongodb,Aggregation Framework,Union,我正在尝试聚合来自不同设备的一些信息。给定一组设备ID,我想计算值出现的次数。我正在努力解决的问题是,我们只想处理每台设备的最后一份报告 例如,4台设备在报告集合中存储了数十万份报告。报告告诉我们是否存在网络关闭事件(布尔值)。我想计算4台设备的上次报告中networkDown为真或假的次数 我正在使用mongoDB 2.4.4 报告与此类似: { "_id":ObjectId("52571500fa1fc70437000001"), "device_id" : ObjectId("51

我正在尝试聚合来自不同设备的一些信息。给定一组设备ID,我想计算值出现的次数。我正在努力解决的问题是,我们只想处理每台设备的最后一份报告

例如,4台设备在报告集合中存储了数十万份报告。报告告诉我们是否存在网络关闭事件(布尔值)。我想计算4台设备的上次报告中networkDown为真或假的次数

我正在使用mongoDB 2.4.4

报告与此类似:

{
  "_id":ObjectId("52571500fa1fc70437000001"),
  "device_id" : ObjectId("51f14f9f9809c4404f00000a"),
  "payload":{
    "name":"Status",
    "properties":{
      "property":{
        "deviceIdentifier":"My Device",
        "networkDown":"false"
      }
    }
  },
  "updated_at":ISODate("2013-10-10T20:58:40.674Z"),
  "created_at":ISODate("2013-10-10T20:58:40.674Z")
}
我可以对所有4台设备的所有记录进行分组。说

  db.report.aggregate(
  [
    { $match: { device_id: 
        {
          $in:         
          [
            ObjectId("51f14f9f9809c4404f00000a"),
            ObjectId("523ab68a9809c4e490000059"),
            ObjectId("522f37b89809c4e8cf000033"),
            ObjectId("522f38019809c4ae070000d3")        
          ]
        }
      }
    },    
    { $group: { _id: "$payload.properties.property.networkDown", total: { $sum: 1 } } }                     
  ])


{
    "result" : [
        {
            "_id" : "true",
            "total" : 2
        },
        {
            "_id" : "false",
            "total" : 278539
        }
    ],
    "ok" : 1
}
但是,如何将查询限制为仅对每个设备的最后一个报告有效


谢谢你的关注

您将首先根据
{updated_at:1}
进行排序。然后根据设备id进行分组,并使用$last运算符仅获取自文档排序以来的最后一个networkDown字段。然后在networkDown属性上执行另一个组。我知道这有点复杂,但问题是:

db.reports.aggregate(
[
 { $match: { device_id: 
        {
          $in:         
          [
            ObjectId("51f14f9f9809c4404f00000a"),
            ObjectId("523ab68a9809c4e490000059"),
            ObjectId("522f37b89809c4e8cf000033"),
            ObjectId("522f38019809c4ae070000d3")        
          ]
        }
      }
    },
    {$sort:{updated_at:1}},
    {$group:
       {_id:"$device_id",
        networkDown:{$last:"$payload.properties.property.networkDown"}
       }
    },
    {$group:{_id:"$networkDown",count:{$sum:1}}}
])

我还没有试过,但应该可以用。如果有任何问题请告诉我

谢谢您的关注!我得到了我期望的结果。按设备id分组并最后拿$。不幸的是,查询时间太长,无法满足需求,因此我想我将不得不使用聚合以外的方法。我希望聚合管道有一种组合集合的方法,这样在分组之前,我可以为每个设备设置$limit 1。谢谢按降序排序和使用$first应有助于提高性能。您可以在更新的_at字段上使用索引以进一步改进。