3

the document in my mongo collection like this:

{
    "_id" : ObjectId("568f7e67676b4ddf133999e8"),
    "auth_dic" : {
        "2406" : [ 
            "44735"
        ],
        "6410" : [ 
            "223423"
        ]
        ...
        ...

    },
    "user_id" : "fdasd23423"
}

this is one user, there are many id like '2406' '6410' in 'auth_dic'

i want to user map_reduce method to statistic how many users have the '2406', how many users have the '6410', and other types. my mapper is:

mapper = Code('''
                function(){
                    this.auth_dic.forEach(function(app_id){
                        emit(app_id, 1);
                    });
                }
            ''')

my reducer is:

reducer = Code('''
                function(key, values){
                    var total = 0;
                    for (var i = 0; i < values.length; i++) {
                        total += values[i];
                    }
                    return total;
                }
            ''')

but the mapper can not work, beacause the function 'forEach' can not user to iterate a dic, what can i do to solve this problem?

styvane
  • 59,869
  • 19
  • 150
  • 156
ray.li
  • 31
  • 2
  • You should consider to change your documents structure and make `auth_dic` an array of subdocument. – styvane Jan 11 '16 at 09:47

1 Answers1

2

Run the following MapReduce operation:

mr = db.runCommand({
    "mapreduce" : "collectionName",
    "map" : function() {
        var map = this.auth_dic;
        for (var key in map) { 
            if (map.hasOwnProperty(key)) { emit(key, 1); }
        }
    },
    "reduce" : function(key, val) { return Array.sum(val); }, 
    "out": "collectionName" + "_keys"
})

Then query the resulting collection so as to find all the counts for the dynamic keys:

db[mr.result].find()
chridam
  • 100,957
  • 23
  • 236
  • 235
  • 1
    Normally a good idea to add a hasOwnProperty now-a-days too else you might iterate keys from prototypes – Sammaye Jan 11 '16 at 10:17