草庐IT

go - 带有聚合和分组的 mgo

coder 2024-07-05 原文

我正在尝试使用 golang mgo 执行查询 为了有效地从连接中获得不同的值,我知道这可能不是在 Mongo 中使用的最佳范例。

像这样:

pipe := []bson.M{

    {
        "$group": bson.M{
            "_id":  bson.M{"user": "$user"},

        },
    },

    {
        "$match": bson.M{
            "_id":  bson.M{"$exists": 1},
            "user": bson.M{"$exists": 1},
            "date_updated": bson.M{
                "$gt": durationDays,
            },
        },

    },

    {
        "$lookup": bson.M{
            "from":         "users",
            "localField":   "user",
            "foreignField": "_id",
            "as":           "user_details",
        },
    },
    {
        "$lookup": bson.M{
            "from":         "organizations",
            "localField":   "organization",
            "foreignField": "_id",
            "as":           "organization_details",
        },
    },

}

err := d.Pipe(pipe).All(&result)

如果我注释掉 $group 部分,查询将按预期返回连接。

如果我按原样运行,我得到 NULL

如果我将 $group 移动到管道的底部,我会得到一个包含 Null 值的数组响应

是否可以使用 $group 进行聚合(目的是模拟 DISTINCT)?

最佳答案

您获得 NULL 的原因是因为您的 $match 过滤器在 $group 阶段之后过滤掉所有文档。

$group 的第一阶段之后,文档仅如下例所示:

  {"_id": { "user": "foo"}},
  {"_id": { "user": "bar"}},
  {"_id": { "user": "baz"}}

它们不再包含其他字段,即 userdate_updatedorganization。如果你想保留他们的值(value),你可以利用 Group Accumulator Operator .根据您的用例,您还可能受益于使用 Aggregation Expression Variables

以使用 mongo shell 为例, 让我们使用 $first operator基本上选择第一次出现。这可能对 organization 有意义,但对 date_updated 没有意义。请选择更合适的累加器运算符。

{"$group": { 
          "_id":"$user", 
          "date_updated": {"$first":"$date_updated"}, 
          "organization": {"$first":"$organization"}
         }
}

请注意,上面还用更简单的 {"_id":"$user"} 替换了 {"_id":{"user":"$user"}} >。

接下来我们将添加 $project stage将组操作中 _id 字段的结果重命名回 user。还可以不加修改地携带其他字段。

{"$project": {
              "user": "$_id", 
              "date_updated": 1, 
              "organization": 1
             }
 }

你的 $match stage可以简化,只需列出 date_updated 过滤器。首先,我们可以删除 _id,因为它在管道中的这一点之前不再相关,而且如果您想确保只处理具有 user 值的文档,您应该将 $match 放在 $group 之前。参见 Aggregation Pipeline Optimization更多。

因此,所有这些组合起来将如下所示:

[
 {"$group":{ 
             "_id": "$user", 
             "date_updated": { "$first": "$date_updated"}, 
             "organization": { $first: "$organization"} 
           }
 },
 {"$project":{ 
               "user": "$_id", 
               "date_updated": 1, 
               "organization": 1
             }
 }, 
 {"$match":{
          "date_updated": {"$gt": durationDays } }
 }, 
 {"$lookup":{
             "from": "users", 
             "localField": "user", 
             "foreignField": "_id", 
             "as": "user_details"
            }
 }, 
 {"$lookup":{
            "from": "organizations", 
            "localField": "organization", 
            "foreignField": "_id", 
            "as": "organization_details"
            }
 }
]

(我知道你知道)最后,根据上面的数据库模式,usersorganizations 集合,根据你的应用程序用例,你可能会重新-考虑嵌入一些值。你可能会发现 6 Rules of Thumb for MongoDB Schema Design有用。

关于go - 带有聚合和分组的 mgo,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46244098/

有关go - 带有聚合和分组的 mgo的更多相关文章

  1. ruby-on-rails - 按天对 Mongoid 对象进行分组 - 2

    在控制台中反复尝试之后,我想到了这种方法,可以按发生日期对类似activerecord的(Mongoid)对象进行分组。我不确定这是完成此任务的最佳方法,但它确实有效。有没有人有更好的建议,或者这是一个很好的方法?#eventsisanarrayofactiverecord-likeobjectsthatincludeatimeattributeevents.map{|event|#converteventsarrayintoanarrayofhasheswiththedayofthemonthandtheevent{:number=>event.time.day,:event=>ev

  2. ruby - 在 Ruby 中创建按公共(public)键值分组的新哈希 - 2

    假设我有一个在Ruby中看起来像这样的哈希:{:ie0=>"Hi",:ex0=>"Hey",:eg0=>"Howdy",:ie1=>"Hello",:ex1=>"Greetings",:eg1=>"Goodday"}有什么好的方法可以将它变成如下内容:{"0"=>{"ie"=>"Hi","ex"=>"Hey","eg"=>"Howdy"},"1"=>{"ie"=>"Hello","ex"=>"Greetings","eg"=>"Goodday"}} 最佳答案 您要求一个好的方法来做到这一点,所以答案是:一种您或同事可以在六个月后理解

  3. ruby-on-rails - 带有 Zeus 的 RSpec 3.1,我应该在 spec_helper 中要求 'rspec/rails' 吗? - 2

    使用rspec-rails3.0+,测试设置分为spec_helper和rails_helper我注意到生成的spec_helper不需要'rspec/rails'。这会导致zeus崩溃:spec_helper.rb:5:in`':undefinedmethod`configure'forRSpec:Module(NoMethodError)对thisissue最常见的回应是需要'rspec/rails'。但这是否会破坏仅使用spec_helper拆分rails规范和PORO规范的全部目的?或者这无关紧要,因为Zeus无论如何都会预加载Rails?我应该在我的spec_helper中做

  4. Ruby:如何使用带有散列的 'send' 方法调用方法? - 2

    假设我有一个类A,里面有一些方法。假设stringmethodName是这些方法之一,我已经知道我想给它什么参数。它们在散列中{'param1'=>value1,'param2'=>value2}所以我有:params={'param1'=>value1,'param2'=>value2}a=A.new()a.send(methodName,value1,value2)#callmethodnamewithbothparams我希望能够通过传递我的哈希以某种方式调用该方法。这可能吗? 最佳答案 确保methodName是一个符号,而

  5. ruby-on-rails - 带有 Pry 的 Rails 控制台 - 2

    当我进入Rails控制台时,我已将pry设置为加载代替irb。我找不到该页面或不记得如何将其恢复为默认行为,因为它似乎干扰了我的Rubymine调试器。有什么建议吗? 最佳答案 我刚发现问题,pry-railsgem。忘记了它的目的是让“railsconsole”打开pry。 关于ruby-on-rails-带有Pry的Rails控制台,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/question

  6. 带有 attr_accessor 的类上的 Ruby instance_eval - 2

    我了解instance_eval和class_eval之间的基本区别。我在玩弄时发现的是一些涉及attr_accessor的奇怪东西。这是一个例子:A=Class.newA.class_eval{attr_accessor:x}a=A.newa.x="x"a.x=>"x"#...expectedA.instance_eval{attr_accessor:y}A.y="y"=>NoMethodError:undefinedmethod`y='forA:Classa.y="y"=>"y"#WHATTT?这是怎么回事:instance_eval没有访问我们的A类(对象)然后它实际上将它添加到

  7. ruby-on-rails - Rails 渲染带有驼峰命名法的 json 对象 - 2

    我在一个简单的RailsAPI中有以下Controller代码:classApi::V1::AccountsControllerehead:not_foundendendend问题在于,生成的json具有以下格式:{id:2,name:'Simpleaccount',cash_flows:[{id:1,amount:34.3,description:'simpledescription'},{id:2,amount:1.12,description:'otherdescription'}]}我需要我生成的json是camelCase('cashFlows'而不是'cash_flows'

  8. arrays - 如何在下面的示例中将两个值数组分组为 n 个值数组? - 2

    我已经有很多两个值数组,例如下面的例子ary=[[1,2],[2,3],[1,3],[4,5],[5,6],[4,7],[7,8],[4,8]]我想把它们分组到[1,2,3],[4,5],[5,6],[4,7,8]因为意思是1和2有关系,2和3有关系,1和3有关系,所以1,2,3都有关系我如何通过ruby​​库或任何算法来做到这一点? 最佳答案 这是基本Bron–Kerboschalgorithm的Ruby实现:classGraphdefinitialize(edges)@edges=edgesenddeffind_maximum_

  9. ruby - 如何将相同的相邻数字分组 - 2

    如果至少有两个相邻的数字相同,格式为,我需要打包.这是我的输入:[2,2,2,3,4,3,3,2,4,4,5]以及预期的输出:"2:3,3,4,3:2,2,4:2,5"到目前为止我试过:a=[1,1,1,2,2,3,2,3,4,4,5]a.each_cons(2).any?do|s,t|ifs==t如果相等,也许可以尝试计数器,但那是行不通的。 最佳答案 您可以使用Enumerable#chunk_while(如果你使用的是Ruby>=2.3):a.chunk_while{|a,b|a==b}.flat_map{|chunk|chu

  10. ruby-on-rails - 在 Ruby 或 Rails 中,hash.merge({ :order => 'asc' }) can return a new hash with a new key. 什么可以返回带有已删除键的新散列? - 2

    在Ruby(或Rails)中,我们可以做到new_params=params.merge({:order=>'asc'})现在new_params是一个带有添加键:order的散列。但是是否有一行可以返回带有已删除key的散列?线路new_params=params.delete(:order)不会工作,因为delete方法返回值,仅此而已。我们必须分3步完成吗?tmp_params=paramstmp_params.delete(:order)returntmp_params有没有更好的方法?因为我想做一个new_params=(params[:order].blank?||para

随机推荐