node.js - 使用 mongoose 在 mongodb 上执行 mapreduce 时不能在 reduce 函数中使用 underscore.js

标签 node.js mongodb mapreduce underscore.js

我有一个电影收藏,每部电影都有几颗星星,例如:

{
    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/

相关文章:

apache - 哈多普 : supporting multiple outputs for Map Reduce jobs

caching - Hadoop 文件中的分布式缓存未找到异常

hadoop - 自定义 Hadoop 类型的 ArrayWritable 实现

node.js - 当前 javascript 版本不支持字符串模板

javascript - 如何在 NodeJS 中使用 require 从本地文件创建 Blob?

node.js - Mongoose 模型架构引用不起作用

python - 在 Python 中管理(即正确终止)MongoDB 守护进程最可接受的方法是什么?

javascript - 使用动态字段名称更新数据

javascript - 为什么我的 pg-query 结果抛出 TypeError

mongodb - 尽管 mongodb 中有数据,为什么 db.database.find() 没有结果?