2017-09-15 105 views
0

我試圖執行使用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)?

回答

1

您得到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