Jadi saya punya koleksi seperti ini:

{
 'region': '1',
 'status': 'a',
 'sum': 100
}
{
 'region': '1',
 'status': 'b',
 'sum': 80
}
{
 'region': '2',
 'status': 'a',
 'sum': 20
}
{
 'region': '2',
 'status': 'a',
 'sum': 30
}

Dan hasil yang diinginkan harus seperti ini:

[
  {
    'region': '1',
    'status_a': 1,
    'status_b': 1,
    'sum': 180
  },
  {
    'region': '2',
    'status_a': 2,
    'sum': 50
  }
]

Ada saran? Jumlah wilayah serta jumlah status dapat bervariasi dan saya harus selalu menampilkan jumlah untuk seluruh region terlepas dari status

P.S jika Anda ingin sangat spesifik dengan jawaban Anda, maka bidang wilayah dan status adalah ObjectId, terima kasih atas sarannya!

1
Hotkuk 12 Mei 2021, 11:23

1 menjawab

Jawaban Terbaik
  • $group oleh region dan status dan hitung status dan jumlahkan
  • $group hanya dengan region dan $concat status_ dan nilainya setelah mengonversi id objek menjadi string menggunakan $toString
  • buat larik status dan statusCount dalam format nilai kunci
  • $arrayToObject konversikan array yang dikonversi di atas menjadi objek
  • $mergeObjects untuk menggabungkan bidang wajib dan objek status
  • $replaceRoot untuk mengganti dokumen gabungan di atas di root
db.collection.aggregate([
  {
    $group: {
      _id: { region: "$region", status: "$status" },
      statusCount: { $sum: 1 },
      sum: { $sum: "$sum" }
    }
  },
  {
    $group: {
      _id: "$_id.region",
      status: {
        $push: {
          k: { $concat: ["status_", { $toString: "$_id.status" }] },
          v: "$statusCount"
        }
      },
      sum: { $sum: "$sum" }
    }
  },
  {
    $replaceRoot: {
      newRoot: {
        $mergeObjects: [
          { $arrayToObject: "$status" },
          {
            resion: "$_id",
            sum: "$sum"
          }
        ]
      }
    }
  }
])

Tempat bermain

1
turivishal 12 Mei 2021, 08:58