我有一个电影收藏,每部电影都有几颗星星,例如:
{
movie: "Pride & Prejudice",
starList: ["Keira Knightley", "Matthew Macfadyen"]
}
{
movie: "Begin Again",
starList: ["Keira Knightley", "Mark Ruffalo"]
}
我想得到一个倒排索引,每个明星都有几部电影
{
明星:“凯拉奈特莉”,
movieList: [《傲慢与偏见》、《重新开始》]
}
这可以通过在 mongodb 上使用 mapreduce 来完成。我将 nodejs 与 mongoose 驱动程序一起使用。以下是代码:
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);
或使用流利的 aggregate()
构建器 API:
Movie.aggregate()
.unwind("starsList")
.group({
"_id": "$starsList",
"movieList": {"$push": "$movie"}
})
.project({
"_id": 0,
"star": "$_id",
"movieList": 1
})
.exec(callback);
关于node.js - 使用 mongoose 在 mongodb 上执行 mapreduce 时不能在 reduce 函数中使用 underscore.js,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39106464/