草庐IT

mongodb - 聚合计算每个标签的数量,这里有两种类型的标签

coder 2023-11-03 原文

我有一个集合,其中的元素可以简化为:

{
  t1 : [1, 3, 6],
  t2 : [8, 9]
}

were in t1t2 可以是 1 到 10 个正整数,不能重复。我需要计算集合中所有文档的 t1 和 t2 中每个数字有多少。

例如,如果我的收藏包含 3 个文档:

{
  t1 : [1, 3, 6],
  t2 : [8, 9]
}, {
  t1 : [1, 2],
  t2 : [8]
}, {
  t1 : [6],
  t2 : [8, 1]
}

我应该有类似的东西

t1 : {
   1 : 2,   // there are 2 elements of 1 in t1
   3 : 1,   // there is 1 element of 3 in t1
   6 : 2,
   2 : 1
}

t2 : {
  8 : 3,    // there are 3 elements of 8 in t2
  9 : 1,
  1 : 1
}

我目前正在做的事情是这样的:

var t1 = {}, t2 = {};
db.coll.find().forEach(function(e){
   // where I am iterating through each element in t1 and t2 to
   // and increase/populate values in t1 and t2
})

虽然这种方法没有错,但我认为聚合框架有更好的方法。是否可以只使用一次聚合来做到这一点?

P.S. 我在示例中显示的输出只是一个示例。任何可以给我所需信息的输出都是合适的。

最佳答案

聚合的单一形式:

db.tags.aggregate([
    { "$project": {
        "_id": 0,
        "t1": 1,
        "t2": 2,
        "type": { "$literal": ["t1","t2"] }
    }},
    { "$unwind": "$type" },
    { "$project": {
        "type": 1,
        "value": { 
            "$cond": [
                { "$eq": [ "$type", "t1" ] },
                "$t1",
                "$t2"
            ]
        } 
    }},
    { "$unwind": "$value" },
    { "$group": {
        "_id": {
            "type": "$type",
            "value": "$value"
        },
        "count": { "$sum": 1 }
    }},
    { "$sort": { "_id.type": 1, "_id.value": 1 } }
])

并输出:

{ "_id" : { "type" : "t1", "value" : 1 }, "count" : 2 }
{ "_id" : { "type" : "t1", "value" : 2 }, "count" : 1 }
{ "_id" : { "type" : "t1", "value" : 3 }, "count" : 1 }
{ "_id" : { "type" : "t1", "value" : 6 }, "count" : 2 }
{ "_id" : { "type" : "t2", "value" : 1 }, "count" : 1 }
{ "_id" : { "type" : "t2", "value" : 8 }, "count" : 3 }
{ "_id" : { "type" : "t2", "value" : 9 }, "count" : 1 }

或者,如果您更喜欢单个文档,只需将结束阶段替换为 $group , 和 $project :

    { "$group": {
        "_id": null,
        "t1": {
            "$push": {
                "$cond": [
                    { "$eq": [ "$_id.type", "t1" ] },
                    { "value": "$_id.value", "count": "$count" },
                    false
                ]
            }
        },
        "t2": {
            "$push": {
                "$cond": [
                    { "$eq": [ "$_id.type", "t2" ] },
                    { "value": "$_id.value", "count": "$count" },
                    false
                ]
            }
        },
    }},
    { "$project": {
        "_id": 0,
        "t1": { "$setDifference": [ "$t1", [false] ] },
        "t2": { "$setDifference": [ "$t2", [false] ] }
    }}

结果:

{ 
    "t1" : [ 
        { "value" : 2, "count" : 1 }, 
        { "value" : 6, "count" : 2 }, 
        { "value" : 3, "count" : 1 }, 
        { "value" : 1, "count" : 2 } 
    ], 
    "t2" : [ 
        { "value" : 1, "count" : 1 },
        { "value" : 9, "count" : 1 },
        { "value" : 8, "count" : 3 } 
    ] 
}

这些无需使用 MongoDB 2.6 中的新运算符即可实现,只是需要多做一些工作。


mapReduce 方法看起来相当简单。由于 mapReduce 的限制,输出当然不是您的格式,但它无需迭代查询即可获得结果:

db.collection.mapReduce(
    function () {
      delete this["_id"];

      for ( var k in this ) {
        var list = this[k];
        list.forEach(function(v) {
          emit( { k: k , v: v }, 1 );
        });
      }
    },
    function (key,values) {
      return values.length;
    },
    { "out": { "inline": 1 } }
)

输出将是:

{ "_id" : { "k" : "t1", "v" : 1 }, "value" : 2 }
{ "_id" : { "k" : "t1", "v" : 2 }, "value" : 1 }
{ "_id" : { "k" : "t1", "v" : 3 }, "value" : 1 }
{ "_id" : { "k" : "t1", "v" : 6 }, "value" : 2 }
{ "_id" : { "k" : "t2", "v" : 1 }, "value" : 1 }
{ "_id" : { "k" : "t2", "v" : 8 }, "value" : 3 }
{ "_id" : { "k" : "t2", "v" : 9 }, "value" : 1 }

还取决于您是否需要灵活使用“键”名称。

关于mongodb - 聚合计算每个标签的数量,这里有两种类型的标签,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23863255/

有关mongodb - 聚合计算每个标签的数量,这里有两种类型的标签的更多相关文章

  1. ruby - 在院子里用@param 标签警告 - 2

    我试图使用yard记录一些Ruby代码,尽管我所做的正是所描述的here或here#@param[Integer]thenumberoftrials(>=0)#@param[Float]successprobabilityineachtrialdefinitialize(n,p)#initialize...end虽然我仍然得到这个奇怪的错误@paramtaghasunknownparametername:the@paramtaghasunknownparametername:success然后生成的html看起来很奇怪。我称yard为:$yarddoc-mmarkdown我做错了什么?

  2. ruby-on-rails - 使用一系列等级计算字母等级 - 2

    这里是Ruby新手。完成一些练习后碰壁了。练习:计算一系列成绩的字母等级创建一个方法get_grade来接受测试分数数组。数组中的每个分数应介于0和100之间,其中100是最大分数。计算平均分并将字母等级作为字符串返回,即“A”、“B”、“C”、“D”、“E”或“F”。我一直返回错误:avg.rb:1:syntaxerror,unexpectedtLBRACK,expecting')'defget_grade([100,90,80])^avg.rb:1:syntaxerror,unexpected')',expecting$end这是我目前所拥有的。我想坚持使用下面的方法或.join,

  3. css - 用 watir 检查标签类? - 2

    我有一个div,它根据表单是否正确提交而改变。我想知道是否可以检查类的特定元素?开始元素看起来像这样。如果输入不正确,添加错误类。 最佳答案 试试这个:browser.div(:id=>"myerrortest").class_name更多信息:http://watir.github.com/watir-webdriver/doc/Watir/HTMLElement.html#class_name-instance_method另一种选择是只查看具有您期望的类的div是否存在browser.div((:id=>"myerrortes

  4. 计算机毕业设计ssm+vue基本微信小程序的小学生兴趣延时班预约小程序 - 2

    项目介绍随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱小学生兴趣延时班预约小程序的设计与开发被用户普遍使用,为方便用户能够可以随时进行小学生兴趣延时班预约小程序的设计与开发的数据信息管理,特开发了小程序的设计与开发的管理系统。小学生兴趣延时班预约小程序的设计与开发的开发利用现有的成熟技术参考,以源代码为模板,分析功能调整与小学生兴趣延时班预约小程序的设计与开发的实际需求相结合,讨论了小学生兴趣延时班预约小程序的设计与开发的使用。开发环境开发说明:前端使用微信微信小程序开发工具:后端使用ssm:VU

  5. HBase Region 简介和建议数量&大小 - 2

    Region是HBase数据管理的基本单位,region有一点像关系型数据的分区。region中存储这用户的真实数据,而为了管理这些数据,HBase使用了RegionSever来管理region。Region的结构hbaseregion的大小设置默认情况下,每个Table起初只有一个Region,随着数据的不断写入,Region会自动进行拆分。刚拆分时,两个子Region都位于当前的RegionServer,但处于负载均衡的考虑,HMaster有可能会将某个Region转移给其他的RegionServer。RegionSplit时机:当1个region中的某个Store下所有StoreFile

  6. ruby - 如何计算 Liquid 中的变量 +1 - 2

    我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我

  7. ruby - 使用 Ruby,计算 n x m 数组的每一列中有多少个 true 的简单方法是什么? - 2

    给定一个nxmbool数组:[[true,true,false],[false,true,true],[false,true,true]]有什么简单的方法可以返回“该列中有多少个true?”结果应该是[1,3,2] 最佳答案 使用转置得到一个数组,其中每个子数组代表一列,然后将每一列映射到其中的true数:arr.transpose.map{|subarr|subarr.count(true)}这是一个带有inject的版本,应该在1.8.6上运行,没有任何依赖:arr.transpose.map{|subarr|subarr.in

  8. ruby - 将n维数组的每个元素乘以Ruby中的数字 - 2

    在Ruby中,是否有一种简单的方法可以将n维数组中的每个元素乘以一个数字?这样:[1,2,3,4,5].multiplied_by2==[2,4,6,8,10]和[[1,2,3],[1,2,3]].multiplied_by2==[[2,4,6],[2,4,6]]?(很明显,我编写了multiplied_by函数以区别于*,它似乎连接了数组的多个副本,不幸的是这不是我需要的)。谢谢! 最佳答案 它的长格式等价物是:[1,2,3,4,5].collect{|n|n*2}其实并没有那么复杂。你总是可以使你的multiply_by方法:c

  9. arrays - 计算数组中的匹配元素 - 2

    给定两个大小相等的数组,如何找到不考虑位置的匹配元素的数量?例如:[0,0,5]和[0,5,5]将返回2的匹配项,因为有一个0和一个5共同;[1,0,0,3]和[0,0,1,4]将返回3的匹配项,因为0有两场,1有一场;[1,2,2,3]和[1,2,3,4]将返回3的匹配项。我尝试了很多想法,但它们都变得相当粗糙和令人费解。我猜想有一些不错的Ruby习惯用法,或者可能是一个正则表达式,可以很好地回答这个解决方案。 最佳答案 您可以使用count完成它:a.count{|e|index=b.index(e)andb.delete_at

  10. ruby - 每个页面上的 Jekyll 分页 - 2

    据我们所知,Jekyll默认分页仅支持index.html,我想创建blog.html并在那里包含分页。有什么解决办法吗? 最佳答案 如果您创建一个名为/blog的目录并在其中放置一个index.html文件,那么您可以向_config.yml表示paginate_path:"blog/page:num"。不是使用根文件夹中的默认index.html作为分页器模板,而是使用/blog/index.html。分页器将根据需要生成类似/blog/page2/和/blog/page3/的页面。这将使您到达yourwebsite.com/b

随机推荐