当前位置: 首页 > 知识库问答 >
问题:

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

冯奇思
2023-03-14

我有已导入收藏的. json-file。

{
    "_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
        }
      ]
}

我想做一些地图缩减,以显示所有用户的评论总数及其平均值。

我试过:

 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

你能帮忙吗?

共有2个答案

苏畅
2023-03-14

我找到了解决方案:

    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

                     }

                   )

数据库。用户。find()为我提供:

    { "_id" : 1, "value" : { "count" : 56, "rating" : 237, "avg" : 4.232142857142857 } }
    { "_id" : 2, "value" : { "count" : 129, "rating" : 479, "avg" : 3.7131782945736433 } }
    { "_id" : 3, "value" : { "count" : 51, "rating" : 199, "avg" : 3.9019607843137254 } }
    { "_id" : 4, "value" : { "count" : 21, "rating" : 88, "avg" : 4.190476190476191 } }
    { "_id" : 5, "value" : { "count" : 198, "rating" : 623, "avg" : 3.1464646464646466 } }
严永丰
2023-03-14

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

db.movie.aggregate([
    { "$unwind": "$ratings" }, 
    { "$group": { 
        "_id": "$ratings.userId", 
        "count": { "$sum": 1 }, 
        "average": { "$avg": "$ratings.rating" } 
    }}
])
 类似资料:
  • 任何人都可以帮助我查询mongo以释放数组,我使用的是mongdb本机驱动程序我的收集文档如下,也请忽略我的objectId它只是示例 而我的预期产出是 我只想解开我的数组,在一个查询中的爱好描述之间添加一个逗号,谢谢你的帮助

  • 我正在查看MongoDB在和投影上的留档。我试图弄清楚如何只返回投影数组字段的子集,但我似乎无法弄清楚。 相关帖子: > 我没有试图从mongob聚合框架中执行$片-获取嵌套数组的第一个文档字段。 我也没有尝试从mongo projection中的仅返回数组值展平子文档,因为我仍然需要顶部文档中的一些字段。 假设我在集合中有以下文档: 我想要执行的查询是: 我希望它只返回数组中为的子文档下的。例如

  • 返回所有字段,但返回NULL。我做错什么了吗? 进一步挖掘,如果我做这样的事情: 以下为打印内容: 查看FacetField源代码:https://github.com/apache/lucene-solr/blob/branch_6_3/lucene/facet/src/java/org/apache/lucene/facet/FacetField.java似乎所有的FacetField都是用“

  • 我正在向elasticsearch发送查询,它会响应其文档中字段的未知顺序。我如何修复elsasticsearch返回文档中字段的顺序?我的意思是,我正在发送这个查询: 当它回应时,它给了我一些不正常的东西。我最后想将其转换为csv,并修复csv标题。有什么方法可以让我得到像doc1:{“field1”,“field2”,“field3”,“field14”}doc2:{“field1”,“fie

  • 我一直在尝试编写一些代码来使用MapReduce查找数字的平均值。 我尝试使用全局计数器来实现我的目标,但是我无法在映射器的< code>map方法中设置计数器值,也无法在缩减器的< code>reduce方法中检索计数器值。 我是否必须在< code>map中使用全局计数器(例如,通过使用所提供的< code>Reporter的< code>incrCounter(key,amount))?或者

  • 我正在使用SQL Server,数据库中有下表: 到目前为止我尝试了什么(错误的,因为它不计算每个组的平均值,而是计算所有列的总平均值):