2014-01-29 47 views
1

我有以下格式的數據:如何找到MongoDB的集合多個occurence嵌套數據

{'user': 'A', 'books' :['One', 'Two','Three','Seven']} 
{'user': 'B', 'books' :['Two', 'Four','Five']} 
{'user': 'C', 'books' :['Five', 'One','Two','Nine','Ten','Twelve']} 
{'user': 'D', 'books' :['One', 'Two','Six']} 

用戶共同面臨的書意味着某種形式的他們之間的協作 的。我的目標是找出有多少本書正在合作 (或者,或者用戶可能會以某種形式進行協作,而不是以任何形式的協作形式的那些合作伙伴)

在這一點上,我確定我不能設計一個將顯示此信息的查詢,所以我想知道,這是mongdb的mapreduce可以做的事情嗎?如果是的話如何?

我以前沒有做過任何mapreduce,但是在mongodb文檔中查看示例,看起來有可能使用mongodb做到這一點。

回答

2

總是比較喜歡Aggregation Framework以上的地圖縮小。它快得多。 你兩個問題都有點不同,首先是書籍正在合作進行:

db.books.aggregate([ 
    {$unwind : "$books"}, 
    {$group: { _id:"$books", count: {$sum: 1}}}, 
    {$match: {count: {$gt: 1}}}, 
    {$sort: {count: -1}} 
]) 
  1. 放鬆身心使得在對書籍
  2. 將每一個用戶和書籍文檔我們總結了總用戶的合作
  3. 過濾掉沒有超過1的計數。沒有合作者。
  4. 排序相反只是爲了好玩

會給輸出:

{ 
    "result" : [ 
      { 
        "_id" : "Two", 
        "count" : 4 
      }, 
      { 
        "_id" : "One", 
        "count" : 3 
      }, 
      { 
        "_id" : "Five", 
        "count" : 2 
      } 
    ], 
    "ok" : 1 
} 

顯示使用超過一次的書籍。

的用戶與他人合作的書是一個涉及多一點:

db.books.aggregate([ 
    {$unwind : "$books"}, 
    {$group: { _id:"$books", users: {$push: "$user"},count: {$sum: 1 }}}, 
    {$match:{count: {$gt: 1}}}, 
    {$unwind: "$users"}, 
    {$group: {_id: "$users", count: {$sum: 1}}}, 
    {$sort: {count: -1}} 
]) 
  1. 像以前一樣放鬆身心的書籍陣列。
  2. 再次將書放在書上,但是這次我們將處理這些書的用戶推到了一個數組中。
  3. 過濾出沒有超過1的計數。沒有合作者。
  4. 放鬆身心的用戶數組,所以我們現在有多種書籍文檔到用戶
  5. 集團用戶和總結書
  6. 排序相反只是爲了好玩

有一個結果:

{ 
    "result" : [ 
      { 
        "_id" : "C", 
        "count" : 3 
      }, 
      { 
        "_id" : "A", 
        "count" : 2 
      }, 
      { 
        "_id" : "D", 
        "count" : 2 
      }, 
      { 
        "_id" : "B", 
        "count" : 2 
      } 
    ], 
    "ok" : 1 
} 

因此,這給了我們爲每個用戶合作的書籍數量。 你可以使用這些更多的交替排序並使用$ project來獲得更好的鍵名,但我認爲這給出了一些有關如何使用聚合框架解決這些問題的概念。

+0

感謝您的詳細解答 – mike

1

它可以通過Aggregation framework

db.books.aggregate([ 
    {$unwind : "$books"}, 
    {$group : {_id : "$books", count : {$sum : 1}}}, 
    {$match : {count : {$gt : 1}}}, 
    {$group : {_id : "total", count : {$sum : 1}}} 
]) 

此查詢計數中出現不止一次的集合,這是你正在尋找的,如果我理解正確的在書的數量來完成。

  1. 首先運行開卷或擴散的本本陣列
  2. 分秒必爭總出場的每本圖書的數字
  3. 三濾出這似乎只是一次
  4. 第四計算的那些出現書籍總數書不止一次
1

這看起來像是一個分組問題。

儘管它可以與MapReduce的解決,它也可以很容易地通過使用聚合框架來解決:http://docs.mongodb.org/manual/aggregation/

我建議類似如下(我可以「翻譯」,如果你想pymongo):

db.collection.aggregate([ 
    {$unwind: "$books" }, 
    {$group: {_id:"$books", usedby: {$sum : 1} } }, 
    {$sort: {"usedby": -1} } 
]) 

它通過$ unwind創建用戶對配對,給出多少用戶使用每本書的計數,然後按降序對它們進行排序。

相關問題