MongoDB:使用MapReduce计算数组元素的重复时间

时间:2015-10-05 16:49:25

标签: mongodb spring-data-mongodb mongodb-java

对于集合的每个文档,它都有一个字符串数组。我如何计算所有这个集合中数组的每个元素的重复时间?现在我可以找到所有不同的元素,但是Map Reduce函数有点棘手,我还没有完全理解。

#cssmenu ul,
#cssmenu li,
#cssmenu span,
#cssmenu a {margin: 0;
  padding: 0;
  position: relative;
  z-index:50;}
#cssmenu:after,
#cssmenu ul:after {content: '';
  display: block;
  clear: both;}
#cssmenu a {color: #333333;
  display: inline-block;
  font-family: 'Lucida Grande', 'Lucida Sans Unicode', Helvetica, Arial, Verdana, sans-serif;
  font-size: 12px;
  min-width: 35px;
  text-align: center;
  text-decoration: none;
  text-shadow: 0 -1px 0 #eeeeee;}
#cssmenu ul {list-style: none;}
#cssmenu > ul > li {float: left;}
#cssmenu > ul > li.active > a {
  background: #d9d9d9 url(images/grad_light.png) repeat-x left bottom;
  background: -moz-linear-gradient(top, #d9d9d9 0%, #bfbfbf 100%);
  background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #d9d9d9), color-stop(100%, #bfbfbf));
  background: -webkit-linear-gradient(top, #d9d9d9 0%, #bfbfbf 100%);
  background: -o-linear-gradient(top, #d9d9d9 0%, #bfbfbf 100%);
  background: -ms-linear-gradient(top, #d9d9d9 0%, #bfbfbf 100%);
  background: linear-gradient(to bottom, #d9d9d9 0%, #bfbfbf 100%);
  filter: progid:dximagetransform.microsoft.gradient(startColorstr='#d9d9d9', endColorstr='#bfbfbf', GradientType=0);
  box-shadow: inset 0 0 10px #979797, inset 0 10px 10px #979797;
  -moz-box-shadow: inset 0 0 10px #979797, inset 0 10px 10px #979797;
  -webkit-box-shadow: inset 0 0 10px #979797, inset 0 10px 10px #979797;
  filter: none;}
#cssmenu > ul > li.active a:hover {
  background: -moz-linear-gradient(top, #d9d9d9 0%, #bfbfbf 100%);
  background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #d9d9d9), color-stop(100%, #bfbfbf));
  background: -webkit-linear-gradient(top, #d9d9d9 0%, #bfbfbf 100%);
  background: -o-linear-gradient(top, #d9d9d9 0%, #bfbfbf 100%);
  background: -ms-linear-gradient(top, #d9d9d9 0%, #bfbfbf 100%);
  background: linear-gradient(to bottom, #d9d9d9 0%, #bfbfbf 100%);
  filter: progid:dximagetransform.microsoft.gradient(startColorstr='#d9d9d9', endColorstr='#bfbfbf', GradientType=0);
  filter: none;}
#cssmenu > ul > li a {
  box-shadow: inset 0 0 0 1px #ffffff;
  -moz-box-shadow: inset 0 0 0 1px #ffffff;
  -webkit-box-shadow: inset 0 0 0 1px #ffffff;
  background: #bfbfbf url(images/grad_light.png) repeat-x left top;
  background: -moz-linear-gradient(top, #ffffff 0%, #e5e5e5 50%, #d7d7d7 51%, #ededed 100%);
  background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #ffffff), color-stop(50%, #e5e5e5), color-stop(51%, #d7d7d7), color-stop(100%, #ededed));
  background: -webkit-linear-gradient(top, #ffffff 0%, #e5e5e5 50%, #d7d7d7 51%, #ededed 100%);
  background: -o-linear-gradient(top, #ffffff 0%, #e5e5e5 50%, #d7d7d7 51%, #ededed 100%);
  background: -ms-linear-gradient(top, #ffffff 0%, #e5e5e5 50%, #d7d7d7 51%, #ededed 100%);
  background: linear-gradient(to bottom, #ffffff 0%, #e5e5e5 50%, #d7d7d7 51%, #ededed 100%);
  filter: progid:dximagetransform.microsoft.gradient(startColorstr='#ffffff', endColorstr='#ededed', GradientType=0);
  border-bottom: 1px solid #d2d2d2;
  border-top: 1px solid #d2d2d2;
  border-right: 1px solid #d2d2d2;
  line-height: 34px;
  padding: 0 35px;
  filter: none;}
#cssmenu > ul > li a:hover {
  background: #ffffff url(images/grad_light.png) repeat-x left bottom;
  background: -moz-linear-gradient(top, #d9d9d9 0%, #bfbfbf 50%, #b0b0b0 51%, #c7c7c7 100%);
  background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #d9d9d9), color-stop(50%, #bfbfbf), color-stop(51%, #b0b0b0), color-stop(100%, #c7c7c7));
  background: -webkit-linear-gradient(top, #d9d9d9 0%, #bfbfbf 50%, #b0b0b0 51%, #c7c7c7 100%);
  background: -o-linear-gradient(top, #d9d9d9 0%, #bfbfbf 50%, #b0b0b0 51%, #c7c7c7 100%);
  background: -ms-linear-gradient(top, #d9d9d9 0%, #bfbfbf 50%, #b0b0b0 51%, #c7c7c7 100%);
  background: linear-gradient(to bottom, #d9d9d9 0%, #bfbfbf 50%, #b0b0b0 51%, #c7c7c7 100%);
  filter: progid:dximagetransform.microsoft.gradient(startColorstr='#ffffff', endColorstr='#ededed', GradientType=0);
  filter: none;}
#cssmenu > ul > li:first-child a {
  border-radius: 5px 0 0 5px;
  -moz-border-radius: 5px 0 0 5px;
  -webkit-border-radius: 5px 0 0 5px;
  border-left: 1px solid #d2d2d2;}
#cssmenu > ul > li:last-child a {
  border-radius: 0 5px 5px 0;
  -moz-border-radius: 0 5px 5px 0;
  -webkit-border-radius: 0 5px 5px 0;}
#cssmenu .has-sub:hover ul {display: block;}
#cssmenu .has-sub ul {display: none;
  position: absolute;
  top: 36px;
  left: -1px;
  min-width: 100%;
  text-align: center;
  *width: 100%;}
#cssmenu .has-sub ul li {text-align: center;}
#cssmenu .has-sub ul li a {border-top: 0 none;
  border-left: 1px solid #d2d2d2;
  display: block;
  font-size: 12px;
  line-height: 120%;
  padding: 9px 5px;
  text-align: center;}

我想得到一个统计结果:3 b:1 c:2 d:1 f:1。

1 个答案:

答案 0 :(得分:2)

您可以采取的替代路线是 aggregation framework 。以上述集合为例

填充测试集合:

db.collection.insert([
    { "_id" : 1, "name" : "ABC1", "actors": ["a", "b", "c"] },
    { "_id" : 2, "name" : "ABC2", "actors" : ["a", "d"] },
    { "_id" : 3, "name" : "XYZ1", "actors" : ["a", "c", "f"] }
])

使用MongoDB 3.4.4或更高版本:

db.collection.aggregate([
    { "$unwind" : "$actors" },
    { "$group": { "_id": "$actors", "count": { "$sum": 1} } },
    { "$group": {
        "_id": null,
        "counts": {
            "$push": {
                "k": "$_id",
                "v": "$count"
            }
        }
    } },
    { "$replaceRoot": {
        "newRoot": { "$arrayToObject": "$counts" }
    } }    
])

<强>输出

{
    a: 3,
    b: 1,
    c: 2,
    d: 1,
    f: 1
}

使用MongoDB 3.2及以下版本:

以下聚合管道操作使用 $unwind 阶段为actors数组中的每个元素输出文档,并输出 $group 阶段按照actors数组中的值对文档进行分组 通过 $sum 运算符计算每个组的文档数(这使得数组元素作为一组出现):

db.collection.aggregate([
    { "$unwind" : "$actors" },
    { "$group": { "_id": "$actors", "count": { "$sum": 1} } }
])

该操作会返回以下结果,这些结果与您的期望非常接近,但不会将文档作为键/值对提供:

/* 0 */
{
    "result" : [ 
        {
            "_id" : "f",
            "count" : 1
        }, 
        {
            "_id" : "d",
            "count" : 1
        }, 
        {
            "_id" : "c",
            "count" : 2
        }, 
        {
            "_id" : "b",
            "count" : 1
        }, 
        {
            "_id" : "a",
            "count" : 3
        }
    ],
    "ok" : 1
}