如何使用MongoDB过滤和汇总一个集合中的数据到另一种格式

时间:2016-10-13 05:07:56

标签: mongodb mongodb-query aggregation-framework

我有一个名为'ctrlcharts'的集合。 e.g。

{  
   "_id" : ObjectId("57fc695492af567031246736"),
   "deviceId" : "A001",
   "sensorId" : "S003",
   "time" : "2016/10/11 12:23:50",
   "charts" : [ 
      {
        "sensor" : "ch_11",
        "value" : 120
      },
      {
        "sensor" : "ch_12",
        "value" : 150
      }
    ]
}

如何使用MongoDB过滤"sensor" : "ch_11"并将数据从一个集合聚合成另一种格式

e.g。

{         
   "time" : "2016/10/11 12:23:50",
   "sensor" : "ch_12",
   "value" : 150       
}

我试过下面的代码

db.ctrlcharts.aggregate([
    { $match: {"deviceId" : "A001", "sensorId" : "S003", "time" : "2016/10/11 12:23:50"}},
    { $project: { 
        _id: 0,
        time : 1 , 
        sensor : "$charts.sensor"
        value : "$charts.value"
      }
    } 
])

但我得到了结果

{         
   "time" : "2016/10/11 12:23:50",
   "sensor" : ["ch_11","ch_12"],
   "value" : [120,150]
}

由于

3 个答案:

答案 0 :(得分:1)

你尝试过最好....只需使用$unwind

db.ctrlcharts.aggregate(
{$unwind:"$charts"},
{$match: {"deviceId" :"A001", "charts.sensor":"ch_12", "time" : "2016/10/11 12:23:50"}},
{$project:{_id:0,time:1, sensor : "$charts.sensor", value :"$charts.value"}}).pretty()

答案 1 :(得分:0)

您可以使用$unwind (aggregation)分隔图表数组。

db.ctrlcharts.aggregate( [ { $unwind : "$charts" } ] )

这将产生类似 -

的结果
{ "_id" : ObjectId("57ff397a007c43ecacf10512"), "deviceId" : "A001", "sensorId" : "S003", "time" : "2016/10/11 12:23:50", "charts" : { "sensor" : "ch_11", "value" : 120 } }
{ "_id" : ObjectId("57ff397a007c43ecacf10512"), "deviceId" : "A001", "sensorId" : "S003", "time" : "2016/10/11 12:23:50", "charts" : { "sensor" : "ch_12", "value" : 150 } }

然后使用您的匹配查询

答案 2 :(得分:0)

使用 $arrayElemAt $filter 运算符更有效地查询数组,而无需 $unwind < / strong>即可。 $unwind 之所以效率不高,是因为它产生了文档的笛卡尔积,即每个数组条目的每个文档的副本,它使用更多内存(聚合管道上可能的内存上限)占总存储量的10%)因此在平整过程中产生以及处理文件需要时间。

$filter 将返回仅包含与过滤条件匹配的元素的数组子集。然后, $arrayElemAt 运算符将从指定数组索引处的筛选数组中返回该元素,以便为您提供所需的子文档。

需要进一步 $project 来展平字段以获得所需的结果:

db.ctrlcharts.aggregate([
    { "$match": { 
        "deviceId": "A001", 
        "sensorId": "S003", 
        "time": "2016/10/11 12:23:50",
        "charts.sensor": "ch_11"
    } },
    { 
        "$project": { 
            "time": 1, 
            "chart": {
                "$arrayElemAt": [
                    "$filter": {
                        "input": "$charts",
                        "as": "item",
                        "cond": { "$eq": ["$$item.sensor", "ch_11"] }
                    }, 0
                ]
            }
        }
    },
    { 
        "$project": { 
            "_id": 0,
            "time": 1, 
            "sensor": "$chart.sensor"
            "value": "$chart.value"
        }
    } 
])