たとえば、次のドキュメントがあります。
{
"_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 は外部ドキュメントを参照します (私は知っていますが、お勧めしません)。price は作業の価格、count は作業が実行された回数、items はすべての作業で使用される材料の配列です。すべての作品の合計金額を取得する必要があります。次の未完成のコードを試しました:
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" }
} }
)
実際には配列を合計しません。作品とアイテムをアンワインドし、$group を使用してアンワインド アイテムを合計します。しかし、思い出しました - service_id、count、price が等しい 2 つの作品が存在する可能性があり、$unwind と $group の後で、そのうちの 1 つを失い、両方のアイテムをまとめてしまいます。
$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
}
]
}