我正在尝试获取文档中某些字段的现有值的计数,以便计算每年数据的这些值的平均值。由于我们注意到(in previous question)我们无法对我的案例使用$ avg聚合,因此我们决定使用sum / count操作。
以下是数据样本:
{
"_id" : ObjectId("593ab6021ccb9b0c0fb226fd"),
"timestamp" : ISODate("2016-11-17T12:36:00.000Z"),
"CO2_CEL_SE_I_001" : 1210,
"CO2_BUR_NE_I_001" : 880
}
{
"_id" : ObjectId("593ab6021ccb9b0c0fb226fe"),
"timestamp" : ISODate("2016-11-17T12:37:00.000Z"),
"CO2_CEL_SE_I_001" : 1210,
"CO2_BUR_NE_I_001" : 880
}
{
"_id" : ObjectId("593ab6021ccb9b0c0fb226ff"),
"timestamp" : ISODate("2016-11-17T12:38:00.000Z"),
"CO2_CEL_SE_I_001" : 1210,
"CO2_BUR_NE_I_001" : 880
}
{
"_id" : ObjectId("593ab63a1ccb9b0c0fb3d3e5"),
"timestamp" : ISODate("2016-02-01T19:26:00.000Z"),
"CO2_CEL_SE_I_001" : 1080
}
{
"_id" : ObjectId("593ab6021ccb9b0c0fb22700"),
"timestamp" : ISODate("2016-11-17T12:39:00.000Z"),
"CO2_CEL_SE_I_001" : 1210,
"CO2_BUR_NE_I_001" : 880
}
然而,获得的结果似乎不是我期望得到的。就在下面是我的问题:
match = {'$match':{'$or':list(map(lambda x:{x:{'$exists': True}}, chosenSensors))}}
group = {'$group':{'_id':{'year':{'$year':'$timestamp'}}}}
project = {'$project':{}}
for chosenSensor in chosenSensors:
group['$group'][chosenSensor+'-Count'] = {'$sum':{'$cond':[{'$ifNull':[True, False]}, 1, 0]}}
group['$group'][chosenSensor+'-Sum'] = {'$sum':{'$ifNull':['$'+chosenSensor, 0]}}
project['$project'][chosenSensor+'-Avg'] = {'$divide':['$'+chosenSensor+'-Sum', '$'+chosenSensor+'-Count']}
project['$project'][chosenSensor+'-Count'] = True
project['$project'][chosenSensor+'-Sum'] = True
sort = {'$sort': {"_id":1}}
pipeline = [match, group, project, sort]
for doc in client["cleanData"]["maison2"].aggregate(pipeline):
print(doc)
以下是我的结果:
selectedSensors = [“CO2_BUR_NE_I_001”,“CO2_CEL_SE_I_001”]
{'_id': {'year': 2016}, 'CO2_BUR_NE_I_001-Count': 5, 'CO2_BUR_NE_I_001-Sum': 3520, 'CO2_CEL_SE_I_001-Count': 5, 'CO2_CEL_SE_I_001-Sum': 5920, 'CO2_BUR_NE_I_001-Avg': 704.0, 'CO2_CEL_SE_I_001-Avg': 1184.0}
selectedSensors = [“CO2_BUR_NE_I_001”]
{'_id': {'year': 2016}, 'CO2_BUR_NE_I_001-Count': 4, 'CO2_BUR_NE_I_001-Sum': 3520, 'CO2_BUR_NE_I_001-Avg': 880.0}
selectedSensors = [“CO2_CEL_SE_I_001”]
{'_id': {'year': 2016}, 'CO2_CEL_SE_I_001-Count': 5, 'CO2_CEL_SE_I_001-Sum': 5920, 'CO2_CEL_SE_I_001-Avg': 1184.0}
查询的行为很奇怪。当我在selectedSensor中定义多个元素的数组时,似乎每个字段的计数是最后一个字段计数的结果。当定义的数组由单个元素组合时,计数是正确的。
答案 0 :(得分:1)
你误解了我在你自己的翻译中给你的代码。
所以这个:
group['$group'][chosenSensor+'-Count'] =
{'$sum':{'$cond':[{'$ifNull':[True, False]}, 1, 0]}}
应该是:
group['$group'][chosenSensor+'-Count'] = {
{'$sum':{'$cond':[{'$ifNull':['$'+chosenSensor, False]}, 1, 0]}
因为你写的是你要求$ifNull
来评估总是存在的True
的布尔值,而不是正确的表达式,它应该是当前的"字段",我们需要测试它是否存在。
所以发生的事情是这些领域总是"总是"被计算在内,这当然是"平均值"我们试图避免的问题。