2012-10-05 34 views
0

想象我有這樣一個集合:的MapReduce /聚合:集團由值嵌套文檔中

{ 
    "_id": "10280", 
    "city": "NEW YORK", 
    "state": "NY", 
    "departments": [ 
      {"departmentType":"01", 
       "departmentHead":"Peter"}, 
      {"departmentType":"02", 
       "departmentHead":"John"} 
    ] 
}, 
{ 
    "_id": "10281", 
    "city": "LOS ANGELES", 
    "state": "CA", 
    "departments": [ 
      {"departmentType":"02", 
       "departmentHead":"Joan"}, 
      {"departmentType":"03", 
       "departmentHead":"Mary"} 
    ] 
}, 
{ 
    "_id": "10284", 
    "city": "MIAMI", 
    "state": "FL", 
    "department": [ 
    "departments": [ 
      {"departmentType":"01", 
       "departmentHead":"George"}, 
      {"departmentType":"02", 
       "departmentHead":"Harry"} 
    ] 
} 

我想獲得每departmentType計數,像這樣:

[{"departmentType":"01", "dCount":2}, 
{"departmentType":"02", "dCount":3}, 
{"departmentType":"03", "dCount":1} 
] 

爲此,我已經嘗試了幾乎所有的東西,但我在網上找到的所有示例都比較容易,其中group by是在文檔根級別的字段上完成的。相反,在這裏我試圖按部門類型進行分組,這似乎破壞了我發現的所有東西。

有關如何使用Mongoose的聚合實現或mapreduce來做到這一點的任何想法?

理想情況下,我想排除所有與< = 1的部門類型和按部門類型排序結果。

謝謝大家提前!

+0

你確定上一個部門是否正確?它看起來不正確。 – cirrus

回答

0

您需要$展開部門數組,這將爲數組中的每個條目創建一個文檔,以便您可以在管道中聚合它們。

不幸的是,您不能預先過濾departmentTypes < = 1,因爲$ size只會取一個確切的值,但您可以將其過濾出結果。這不是很好,但它的工作原理。此示例僅對具有2個部門的記錄進行預過濾,但僅用於演示,您可能希望放棄第一個$匹配,因爲我們過濾出< = 1,並在稍後對結果進行第二次$匹配;

db.runCommand({ 
    aggregate: "so", 
    pipeline: [ 
     { // filter out only records with 2 departments 
      $match: { 
       departments: { $size: 2 } 
      } 
     }, 
     // unwind - create a doc for each department in the array 
     { $unwind: "$departments" }, 
     { // aggregate sum of departments by type 
      $group: { 
       _id: "$departments.departmentType", 
       count: { $sum: 1 }, 
      } 
     }, 
     { // filter out departments with <=1 
      $match: { 
       count: { $gt: 1 }, 
      } 
     }, 
     { // rename fields as per example 
      $project: { 
       _id: 0, 
       departmentType: "$_id", 
       dCount: "$count", 
      } 
     } 
    ] 
}); 

請注意,我還假設你以前的JSON的樣品有一個錯字,和「部門」實際上並不存在。假設所有文檔與前兩個文檔具有相同的模式,此代碼將工作。

如果您對所獲得的實際字段名稱沒有打擾,請隨意放棄第一個$匹配項和最後一個$項目。

+0

嗨,OK試過,情侶概率愚蠢的事情:重寫了語法'mongoose.connection.db.executeDbCommand(...'並添加',功能(ERR,dbres){ \t \t \t如果(ERR) \t \t \t \t擲ERR; \t \t \t別的 \t \t \t \t的console.log(dbres); \t \t \t \t});'在端部捕捉的結果。 然後它說'聚合:「所以」,「沒有這樣的CMD:」聚合「。 有什麼想法? 我確實重複使用了第一個$匹配: '$ match:{ departmentThatExist:{「departments.departmentType」:{$ exists:true}}'排除沒有departmentType的元素。 \t \t \t \t \t} –

+0

您使用的是MongoDB的版本是否低於2.2?彙總內容直到當前最新版本才發佈。 – cirrus

+0

在給定問題陳述的情況下,$ size上的第一個$匹配不是正確的過濾器。最後的$匹配將擺脫只有一次出現的部門類型。根據原始要求,最後還應該有一個$類。 –