1

I am creating a Map function in MongoDB that have a problem as soon as I use forEach() on an array.

This is how a user might look like:

"channels" : [
    "Channel 1",
    "Channel 2",
],
"user_id" : "somehash"

This is my map function that is causing error:

var map = function() {
    if(this.channels && this.user_id) {

        var user_id = this.user_id;

        this.channels.forEach(function(z, user_id) {
            emit(z, {user: user_id});
        });
    }
}

When I am running my Map/Reduce in mongo I use the following command and I get also the following error:

> db.users.mapReduce(map, reduce, {out : "myoutput" });
Wed Aug  1 12:48:11 uncaught exception: map reduce failed:{
    "assertion" : "map invoke failed: JS Error: TypeError: this.channels.forEach is not a function nofile_b:3",
    "assertionCode" : 9014,
    "errmsg" : "db assertion failure",
    "ok" : 0
}

I've tried some different approaches and none seem to work, this might be an easy problem but I can't see where I do it wrong.

Would be glad to get some help on this issue.

Thanks!

5
  • Not sure what variable type is this.channels, but it seams it's not an array or object. How are you creating it? Commented Aug 1, 2012 at 11:21
  • stackoverflow.com/a/5572089/752568 Commented Aug 1, 2012 at 11:22
  • I am creating it in php with the mongo extension and it looks like this: array('channels' => $channels) and $channels look like this: array('channel 1', 'channel 2') Commented Aug 1, 2012 at 11:27
  • the issue is not in the PHP it's in the JavaScript. if you do typeof(variable) it should tell you what is this.channel Commented Aug 1, 2012 at 11:38
  • Yeah it seems like it is an object. How come btw? And can I do this some other way? Can I convert it to an array? Commented Aug 1, 2012 at 12:12

1 Answer 1

1

Fixed it by using for instead of forEach, since it still was a vector I could use .length on it.

Solution:

var map = function() {
    if(this.channels && this.user_id) {
        var user_id = this.user_id;
        for(var i = 0, imax = this.channels.length; i<imax; i++) {
            emit(this.channels[i], {user: user_id});
        }   
    }
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.