使用mongoose对MongoDB进行mapreduce时,不能使用underscore.js中的reduce函数

我有一个电影collections,每部电影有几个明星,例如:

{ movie: "Pride & Prejudice", starList: ["Keira Knightley", "Matthew Macfadyen"] } { movie: "Begin Again", starList: ["Keira Knightley", "Mark Ruffalo"] } 

我想得到一个倒序索引,每个明星都有几部电影

{ star: "Keira Knightley", movieList: ["Pride & Prejudice", "Begin Again"] }

这可以通过在MongoDB上使用mapreduce来完成。 我用mongoose驱动程序使用nodejs。 以下是代码:

 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)); }); 

我得到了一个错误,表明我不能在reduce函数中使用underscore.js。

 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) 

使用聚合框架的一个非常简单的方法如下:

 Movie.aggregate([ { "$unwind": "$starsList" }, { "$group": { "_id": "$starsList", "movieList": {"$push": "$movie"} } }, { "$project": { "_id": 0, "star": "$_id", "movieList": 1 } } ]).exec(callback); 

或者使用stream利的aggregate()构build器API:

 Movie.aggregate() .unwind("starsList") .group({ "_id": "$starsList", "movieList": {"$push": "$movie"} }) .project({ "_id": 0, "star": "$_id", "movieList": 1 }) .exec(callback); 

我可能在这里错了。 但是我认为当你尝试在reduce方法中使用下划线方法时,你的_variables没有所有的方法或访问你必须使用不同的方法。 我会build议像这样尝试

 _['pluck'](....) 

还要检查_variables,看看你是否正确地得到了范围内的所有方法。

希望这可以帮助。