Find count of maximum consecutive records based on one field in Mongodb Query

前端 未结 1 1791
夕颜
夕颜 2021-02-06 08:31

I want to find the count of maximum consecutive records based on one particular field.

My db.people collection after finding sort based on field is:

1条回答
  •  死守一世寂寞
    2021-02-06 08:46

    You can do this mapReduce operation.

    First the mapper:

    var mapper = function () {
    
    
        if ( this.flag == true ) {
            totalCount++;
        } else {
            totalCount = 0;
        }
    
        if ( totalCount != 0 ) {
            emit (
            counter,
            {  _id: this._id, totalCount: totalCount }
        );
        } else {
          counter++;
        }
    
    };
    

    Which keeps a running count of the total times that the true value is seen in flag. If that count is more than 1 then we emit the the value, also containing the document _id. Another counter which is used for the key is incremented when the flag is false, in order to have a grouping "key" for the matches.

    Then the reducer:

    var reducer = function ( key, values ) {
    
        var result = { docs: [] };
    
        values.forEach(function(value) {
            result.docs.push(value._id);
            result.totalCount = value.totalCount;
        });
    
        return result;
    
    };
    

    Simply pushes the _id values onto a result array along with the totalCount.

    Then run:

    db.people.mapReduce(
        mapper,
        reducer,
       { 
           "out": { "inline": 1 }, 
           "scope": { 
               "totalCount": 0, 
               "counter": 0 
           }, 
           "sort": { "updated_at": 1 } 
       }
    )
    

    So with the mapper and reducer functions, we then define the global variables used in "scope" and pass in the "sort" that was required on updated_at dates. Which gives the result:

    {
        "results" : [
            {
                "_id" : 1,
                "value" : {
                    "docs" : [
                         3,
                         4
                     ],
                     "totalCount" : 2
                }
            },
            {
                "_id" : 2,
                "value" : {
                "docs" : [
                    7,
                    8,
                    5
                 ],
                 "totalCount" : 3
                 }
            }
        ],
        "timeMillis" : 2,
        "counts" : {
                "input" : 7,
                "emit" : 5,
                "reduce" : 2,
                "output" : 2
        },
        "ok" : 1,
    }
    

    Of course you could just skip the totalCount variable and just use the array length, which would be the same. But since you want to use that counter anyway it's just added in. But that's the principle.

    So yes, this was a problem suited to mapReduce, and now you have an example.

    0 讨论(0)
提交回复
热议问题