计算MongoDB中的值更改量

时间:2014-11-21 17:15:55

标签: mongodb mongodb-query

我有一个数据库,例如:

 { "_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

1 个答案:

答案 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})