我有一个数据库,例如:
{ "_id": ObjectId("54575132a8269c77675ace49"),"power": false, "time": 1415008560000}
{ "_id": ObjectId("54575132a8269c77675ace50"),"power": true, "time": 1415008570000}
{ "_id": ObjectId("54575132a8269c77675ace51"),"power": false, "time": 1415008580000}
{ "_id": ObjectId("54575132a8269c77675ace52"),"power": false, "time": 1415008590000}
{ "_id": ObjectId("54575132a8269c77675ace53"),"power": true, "time": 1415008600000}
{ "_id": ObjectId("54575132a8269c77675ace54"),"power": false, "time": 1415008610000}
如何计算功率的变化量真变为假且相反?
我可以遍历所有条目并增加一些变量,如果以前的值不同于实际值,但是如何在mongo中执行此操作?
对于此示例,结果应为4
答案 0 :(得分:0)
您可以使用聚合框架来执行此操作:
db.yourCollection.aggregate({ $group:{ _id:"$power", count:{$sum:1} } })
应该会给你以下结果:
{_id:true,count:2}
{_id:false, count:4}
通过从总文档计数(db.yourCollection.count()
)中减去这两个值的差异,您应该具有状态更改的数量:
var cursor = db.yourCollection.aggregate({ $group:{ _id:"$power", count:{$sum:1} } });
var count = db.yourCollection.count();
var changes = count - Math.abs(cursor[0].count - cursor[1].count);
根据@ JohhnyHK的敏锐眼光,他发现了上述问题。所有的荣誉,赞成和他一样。
为了有效地计算大型集合的变化,使用给定的约束,曾经可以使用map / reduce来计算变化,即使对于非常大的集合也应该非常有效。
var numberOfStateChanges = db.yourCollection.mapReduce(
// Mapping function
function(){
// Since in the sample data, there is no reasonable
// field for a key, we use an artificial one: 0
emit(0,this.power);
},
// Reduce function
function(key,values){
// The initial number of changes is 0
var changes=0;
// Our initial state, which does not count towards the changes,...
var state = values[0];
// ... hence we start to compare with the second item in the values array
for (var idx=1; idx < value.length; idx++){
// In case the current state is different from
// the one we are comparing with it, we have a state change
if(value[idx] != state) {
//... which we count...
changes +=1;
// ...and save.
state=value[idx]
}
}
return changes;
},
{
// We make sure the values are fed into the map function in the correct order
sort:{time:1},
// and return it directly instead of putting it into a collection, so we can process it
out:{inline:1}
}
).results[0].value
现在numberOfStateChanges
保存了正确的状态更改次数。
为了有效处理这个map / reduce,我们需要一个关于我们排序的字段的索引,time
:
db.yourCollection.ensureIndex({time:1})