的MgO聚集和分组

问题描述:

我试图执行使用golang氧化镁 有效地得到一个加入不同的值的查询,我明白,这可能不是蒙戈与之合作的最佳范例。的MgO聚集和分组

事情是这样的:

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到管道的底部我得到空数组响应值

是否有可能做做一个聚合$group(目标是模拟DISTINCT)?

您得到NULL的原因是因为您的$match筛选器正在筛选出$group阶段之后的所有文档。

您的$group第一阶段后的文档仅作为举例如下:

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

他们不再包含其他字段即userdate_updatedorganization。如果你想保留它们的值,你可以使用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有用。

+0

感谢您的全面回答和解释! – avrono