Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mongodb 子文档中字段的返回计数和平均值_Mongodb_Mongodb Query_Aggregation Framework - Fatal编程技术网

Mongodb 子文档中字段的返回计数和平均值

Mongodb 子文档中字段的返回计数和平均值,mongodb,mongodb-query,aggregation-framework,Mongodb,Mongodb Query,Aggregation Framework,我已经将.json文件导入到我的集合中 { "_id" : ObjectId("5739ee85daa49f685e316fc6"), "id" : 38, "title" : "It Takes Two (1995)", "genre" : "Comedy", "ratings" : [ { "userId" : 26, "rating" : 2 }, {

我已经将.json文件导入到我的集合中

{
    "_id" : ObjectId("5739ee85daa49f685e316fc6"),
    "id" : 38,
    "title" : "It Takes Two (1995)",
    "genre" : "Comedy",
    "ratings" : [
        {
            "userId" : 26,
            "rating" : 2
        },
        {
            "userId" : 531,
            "rating" : 2
        },
        {
            "userId" : 1054,
            "rating" : 2
        },
        {
            "userId" : 1068,
            "rating" : 2
        },
        {
            "userId" : 1221,
            "rating" : 5
        },
        {
            "userId" : 1434,
            "rating" : 4
        },
        {
            "userId" : 1448,
            "rating" : 1
        },
        {
            "userId" : 1645,
            "rating" : 5
        },
        {
            "userId" : 1647,
            "rating" : 1
        },
        {
            "userId" : 1958,
            "rating" : 3
        },
        {
            "userId" : 2010,
            "rating" : 1
        },
        {
            "userId" : 2042,
            "rating" : 1
        },
        {
            "userId" : 2063,
            "rating" : 1
        },
        {
            "userId" : 2106,
            "rating" : 1
        },
        {
            "userId" : 2116,
            "rating" : 3
        },
        {
            "userId" : 2541,
            "rating" : 5
        },
        {
            "userId" : 2777,
            "rating" : 3
        },
        {
             "userId" : 3013,
             "rating" : 2
        },
        {
             "userId" : 3029,
             "rating" : 2
        },
        {
             "userId" : 3111,
             "rating" : 4
        },
        {
             "userId" : 4387,
             "rating" : 1
        },
        {
             "userId" : 4572,
             "rating" : 5
        },
        {
             "userId" : 5361,
             "rating" : 5
        }
      ]
}
我想做一些map reduce,以便向所有用户显示他们的评论总数及其平均值

我试过:

 var map = function(){emit(this.ratings.userId, 1);}

 var reduce = function(key, values){var res = 0;
 values.forEach(function(v){ res += 1});
 return {count: res};
 }

 db.movie.mapReduce(map, reduce, { out: "users" });

 db.users.find()
 { "_id" : null, "value" : { "count" : 39 } }
我不知道为什么它会显示\u id:null。我想这个.ratings.userId是错误的。但是这个.ratings[userId]也不起作用

我预计会出现以下情况:

userId:10, count:2000
userId:20, count:500

您可以提供帮助吗?

您使用了错误的工具。您需要使用允许访问聚合管道的方法。在您的管道中,您需要使用运算符对“ratings”数组进行非标准化。从中,您可以通过“userId”对文档进行简单分组并使用和累加器运算符,它们分别返回字段的总和和平均值

db.movie.aggregate([
{“$unwind”:“$ratings”},
{“$group”:{
“_id”:“$ratings.userId”,
“计数”:{“$sum”:1},
“平均值”:{“$avg”:“$ratings.rating”}
}}
])

您使用了错误的工具。您需要使用允许访问聚合管道的方法。在管道中,您需要使用运算符对“ratings”数组进行非标准化。从这里,您可以简单地按“userId”对文档进行分组,并使用和累加器运算符,它们分别返回字段的总和和平均值

db.movie.aggregate([
{“$unwind”:“$ratings”},
{“$group”:{
“_id”:“$ratings.userId”,
“计数”:{“$sum”:1},
“平均值”:{“$avg”:“$ratings.rating”}
}}
])
我找到了解决方案:

    var mapFunction = function() {
                       for (var idx = 0; idx < this.ratings.length; idx++) {
                           var key = this.ratings[idx].userId;
                           var value = {
                                         count: 1,
                                         rating: this.ratings[idx].rating
                                       };
                           emit(key, value);
                       }
                    };


   var reduceFunction = function(keyUSERID, countObjVals) {
                     reducedVal = { count: 0, rating: 0 };

                     for (var idx = 0; idx < countObjVals.length; idx++) {
                         reducedVal.count += countObjVals[idx].count;
                         reducedVal.rating += countObjVals[idx].rating;
                     }

                     return reducedVal;
                  };

   var finalizeFunction = function (key, reducedVal) {

                       reducedVal.avg = reducedVal.rating/reducedVal.count;

                       return reducedVal;

                    };

   db.movies.mapReduce( mapFunction,
                     reduceFunction,
                     {
                       out: "users",
                       finalize: finalizeFunction

                     }

                   )
我找到了解决办法:

    var mapFunction = function() {
                       for (var idx = 0; idx < this.ratings.length; idx++) {
                           var key = this.ratings[idx].userId;
                           var value = {
                                         count: 1,
                                         rating: this.ratings[idx].rating
                                       };
                           emit(key, value);
                       }
                    };


   var reduceFunction = function(keyUSERID, countObjVals) {
                     reducedVal = { count: 0, rating: 0 };

                     for (var idx = 0; idx < countObjVals.length; idx++) {
                         reducedVal.count += countObjVals[idx].count;
                         reducedVal.rating += countObjVals[idx].rating;
                     }

                     return reducedVal;
                  };

   var finalizeFunction = function (key, reducedVal) {

                       reducedVal.avg = reducedVal.rating/reducedVal.count;

                       return reducedVal;

                    };

   db.movies.mapReduce( mapFunction,
                     reduceFunction,
                     {
                       out: "users",
                       finalize: finalizeFunction

                     }

                   )

对此,您可能不需要mapReduce。你认为他们评论的数量和平均值是什么意思?例如,用户ID“1”评级为“玩具总动员”(4.0)、“教父”(5.0)、“美国美女”(5.0)、“海底总动员”(4.0)。因此,他的评论总数是4,平均值是4.5。请尝试在
db.movie.find().pretty()
的输出中发布评论,以便我们可以看到您的数据。顺便说一句,在你的问题上使用编辑链接。不要在评论中发布。好的,我发布了我的数据。如果使用mapReduce,则映射函数“ratings”没有“userId”属性中存在错误。您的reduce函数也需要修复。最后,要获得mapReduce与“计数”的平均值,您需要做的还不止这些。您可能不需要mapReduce来实现这一点。你认为他们评论的数量和平均值是什么意思?例如,用户ID“1”评级为“玩具总动员”(4.0)、“教父”(5.0)、“美国美女”(5.0)、“海底总动员”(4.0)。因此,他的评论总数是4,平均值是4.5。请尝试在
db.movie.find().pretty()
的输出中发布评论,以便我们可以看到您的数据。顺便说一句,在你的问题上使用编辑链接。不要在评论中发布。好的,我发布了我的数据。如果使用mapReduce,则映射函数“ratings”没有“userId”属性中存在错误。您的reduce函数也需要修复。最后,要使用mapReduce和“计数”获得平均值,您需要做更多的工作。