2016-02-29 119 views
0

我有一個集合的MongoDB這樣的比賽:MongoDB中查找基於計數聚集

{"uid": "01370mask4", 
"title": "hidden", 
"post: "hidden", 
"postTime": "01-23, 2016", 
"unixPostTime": "1453538601", 
"upvote": [2, 3]} 

,我想選擇從用戶記錄後5級以上的職位。結構應該是一樣的,我只是不需要那些沒有很多帖子的用戶的文檔。

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

現在我被困在如何使用計數值來查找。我搜索了但沒有找到任何方法將計數值通過uid添加回相同的集合。保存聚合輸出並將它們連接在一起似乎不受mongodb支持。請指教,謝謝!

更新:

對不起,我以前沒有說清楚。感謝您的及時答覆!我想要一個原始集合的子集,包括髮布文本,發佈時間戳等。我不想要一個聚合輸出的子集。

+0

我不是在你的架構清晰正確的字段名稱,我只是用我的回答一些樣品場... – zangw

+0

可以爲您提供樣品輸入文檔和所需輸出你想要的? –

+0

我認爲你的原始問題非常清楚,後來的更新很混亂 - 你怎麼能用聚合方法得到帖子的詳細信息?你是否想要選擇超過5個帖子的用戶的帖子? –

回答

1

如果沒有成千上萬的文件,那麼你可以嘗試一種快捷的方式來實現你是什麼使用一個骨料和另一個查找查詢,試圖

彙總查詢:

var users = db.collection.aggregate(
    [ 
    {$group:{_id:'$uid', count:{$sum:1}}}, 
    {$match:{count:{$gt:5}}}, 
    {$group:{_id:null,users:{$push:'$_id'}}} 
    ] 
).toArray()[0]['users'] 

那麼它是一個ST raight提前查詢找到特定用戶:

db.collection.find({uid: {$in: users}}) 
+0

非常感謝!我不知道'toArray'方法,它工作!我有18M文件,經過聚合和查找後,我得到了9M,並且在聚合過程中我使用了'allowDiskUse:true',否則它會彈出「內存超出」errmsg。這花了一段時間,並不快,但它確實解決了我的問題。非常感謝! – leoce

1

只需添加$match與正確的查詢您的組後,它的工作原理:

db.collection.aggregate(
    [ 
    { $group : { _id : "$uid", count: { $sum: 1 } } }, 
    { $match : { count : { $gt : 5 } } 
    ] 
) 
1

請嘗試這一個選擇用戶超過5個帖子。要使用$first保留原始字段,如果$uid是唯一的,請添加如下字段。

db.collection.aggregate([ 
    {$group: { 
      _id: '$uid', 
      title: {$first: '$title'}, 
      post: {$first:'$post'}, 
      postTime:{$first: '$postTime'}, 
      unixPostTime:{$first: '$unixPostTime'}, 
      upvote:{$first: '$upvote'}, 
      count: {$sum: 1} 
    }}, 
    {$match: {count: {$gte: 5}}}]) 
) 

如果對於同一$uid多個值,你應該使用$push$group的數組。


如果您想保存結果DB,請嘗試如下

var cur = db.collection.aggregate(
    [ 
    {$group: { 
      _id: '$uid', 
      title: {$first: '$title'}, 
      post: {$first:'$post'}, 
      postTime:{$first: '$postTime'}, 
      unixPostTime:{$first: '$unixPostTime'}, 
      upvote:{$first: '$upvote'}, 
      count: {$sum: 1} 
    }}, 
    {$match: {count: {$gte: 5}}} 
    ] 
) 
cur.forEach(function(doc) { 
    db.collectioin.update({_id: doc._id}, {/*the field should be updated */}); 
}); 
+0

謝謝!我嘗試了'db.collection.aggregate([{$ group:{_id:「$ uid」,title:「$ title」,post:「$ post」,postTime:「$ postTime」,unixPostTime:「$ unixPostTime」, upvote:「$ upvote」,count:{$ sum:1}}},{$ match:{count:{$ gt:5}}}])'但它保持失敗:'「errmsg」:「exception:the組聚合字段「標題」必須定義爲對象內的表達式「,」代碼「:15951,」ok「:0' – leoce

+0

感謝您的持續建議!我認爲'$ first'與'count'有衝突,因爲'$ first'只適用於有1個帖子的用戶。雖然'$ push'方法看起來有效,但它會創建一個嵌套文檔,如[在mongodb中合併兩個集合](http://stackoverflow.com/a/9723549/1907154),但我仍想保留原始結構。這就是爲什麼我沒有遵循合併方法,我說「將它們連接在一起(原始和聚合輸出)不被mongodb支持」。 – leoce

+0

@leoce,是的,'$ first'僅用於文檔的唯一'uid'。但是,如果一個'uid'有多個文檔,''push'應該在這裏使用。 – zangw