2014-02-16 36 views
0

例如,我有以下文件:

{ 
    "_id" : ObjectId("52ffddd3c69e40174c046d67"), 
    "works" : [ 
     { 
      "service_id" : ObjectId("52ffd576c69e40174c046d64"), 
      "price" : 150, 
      "count" : 3, 
      "items" : [ 
       { 
        "price" : 5, 
        "amount" : 10 
       }, 
       { 
        "price" : 7, 
        "amount" : 3 
       } 
      ] 
     }, 
     { 
      "service_id" : ObjectId("52ffd56fc69e40174c046d63"), 
      "price" : 100, 
      "count" : 2 
     } 
    ] 
} 

其中:service_id是指一些外部文件(我知道,它不推薦),價格是價格工作,計數多少次做工已經完成,並物品是材料陣列,用於全部作品。 我需要爲所有作品獲得總價。我試着以下未完成代碼:

db.service_cards.aggregate(
    { $match: {_id: ObjectId("52ffddd3c69e40174c046d67") } }, 
    { $unwind: "$works" }, 
    { $project: { 
     "works.service_id": 1, 
     "works.price": 1, 
     "works.count": 1, 
     "works.items": { 
      "$cond": [ 
       { $eq: [ "$works.items", []] }, 
       [{ 
        "price": 0, 
        "amount": 0 
       }], 
       "$works.items" 
      ], 
     } 
    } }, 
    { $project: { 
     "works.service_id": 1, 
     "works.price": 1, 
     "works.count": 1, 
     "works.items": { 
      "$ifNull": [ 
       "$works.items", 
       [{ 
        "price": 0, 
        "amount": 0 
       }] 
      ], 
     } 
    } }, 
    { $unwind: "$works.items" }, 
    { $project: { 
     "service_id": "$works.service_id", 
     "price": "$works.price", 
     "count": "$works.count", 
     "items_cost": { $multiply: ["$works.items.price", "$works.items.amount"] }, 
    } }, 
    { $group: { 
     _id: "$service_id", 
     "sum_items": { $sum: "$items_cost" }, 
     "price": { $avg: "$price" }, 
     "count": { $avg: "$count" } 
    } } 
) 

實際上它並不總結陣列 - 它解開工程和項目,然後使用$組總結unwinded項目。但後來我記得 - 可能有兩件作品具有相同的service_id,數量和價格,在$ unwind和$ group之後,我會失去其中一件作品,將兩件作品放在一起。

有沒有任何方法可以在沒有$ unwind的情況下在文檔中獲得數組$ sum?

編輯: 我希望收到作品名單沒有他們的項目,但總項目費用:

{ 
    "_id" : ObjectId("52ffddd3c69e40174c046d67"), 
    "works" : [ 
     { 
      "service_id" : ObjectId("52ffd576c69e40174c046d64"), 
      "price" : 150, 
      "count" : 3, 
      "items_cost" : 71 
     }, 
     { 
      "service_id" : ObjectId("52ffd56fc69e40174c046d63"), 
      "price" : 100, 
      "count" : 2, 
      "items_cost": 0 
     } 
    ] 
} 
+0

簡短的回答是沒有。長的答案取決於你期望**做什麼和作爲結果文件接收。目前尚不清楚你的問題。也許如果你添加了你想要和期望的東西,那麼人們可以幫助解決你的問題。通過添加我們的意思是,編輯你的問題,包括這一點,並澄清事情。 –

回答

0

我想,這是不是更好的解決方案,但它是短暫的,做什麼你想要:

db.service_cards.find().forEach(function (document) { 
    var works = document.works || []; 
    var result = []; 
    works.forEach(function (work) { 
     var items = work.items || []; 
     var itemsCost = 0; 
     items.forEach(function (item) { 
      itemsCost += item.price * item.amount; 
     }); 
     var resultObj = { 
      service_id: work.service_id, 
      price: work.price, 
      count: work.count, 
      items_cost: itemsCost 
     }; 
     result.push(resultObj); 
    }); 
    print({ 
     _id: document._id, 
     works: result 
    }); 
})