I have a movie collection, each movie has several stars, for example:
{
movie: "Pride & Prejudice",
starList: ["Keira Knightley", "Matthew Macfadyen"]
}
{
movie: "Begin Again",
starList: ["Keira Knightley", "Mark Ruffalo"]
}
And I want to get an Inverted Index, each star has several movies
{
star: "Keira Knightley",
movieList: ["Pride & Prejudice", "Begin Again"]
}
This can be accomplished by using mapreduce on mongodb. I use nodejs with mongoose driver. Following is the code:
var _ = require("underscore");
var o = {};
o.scope = { _: _ };
o.map = function()
{
var movie = this.movie;
this.starList.forEach(function(star)
{
emit(star, { movieList: [movie]});
});
};
o.reduce = function(k, vals)
{
var movieList = _.flatten(_.pluck(vals, "movieList"));
return { movieList: movieList};
};
Movie.mapReduce(o).then(function(results)
{
console.log(JSON.stringify(results, null, 4));
});
I got an error which shows I cannot use underscore.js in reduce function.
MongoError: TypeError: _.pluck is not a function :
_funcs2@:8:34
at Function.MongoError.create (/app/node_modules/mongoose/node_modules/mongodb/node_modules/mongodb-core/lib/error.js:31:11)
at commandCallback (/app/node_modules/mongoose/node_modules/mongodb/node_modules/mongodb-core/lib/topologies/server.js:1187:66)
at Callbacks.emit (/app/node_modules/mongoose/node_modules/mongodb/node_modules/mongodb-core/lib/topologies/server.js:119:3)
at null.messageHandler (/app/node_modules/mongoose/node_modules/mongodb/node_modules/mongodb-core/lib/topologies/server.js:358:23)
at Socket.<anonymous> (/app/node_modules/mongoose/node_modules/mongodb/node_modules/mongodb-core/lib/connection/connection.js:292:22)
at emitOne (events.js:77:13)
at Socket.emit (events.js:169:7)
at readableAddChunk (_stream_readable.js:153:18)
at Socket.Readable.push (_stream_readable.js:111:10)
at TCP.onread (net.js:536:20)