Tidak mungkin melakukan jenis komputasi yang Anda gambarkan dengan kerangka kerja agregasi - dan itu tidak karena tidak ada $unwind
metode untuk non-array. Bahkan jika objek person:value adalah dokumen dalam larik, $unwind
tidak akan membantu.
Fungsionalitas "kelompokkan menurut" (baik di MongoDB atau di basis data relasional apa pun) dilakukan pada nilai bidang atau kolom. Kami mengelompokkan berdasarkan nilai bidang dan jumlah/rata-rata/dll berdasarkan nilai bidang lain.
Contoh sederhana adalah varian dari apa yang Anda sarankan, bidang peringkat ditambahkan ke kumpulan artikel contoh, tetapi bukan sebagai peta dari pengguna ke peringkat tetapi sebagai larik seperti ini:
{ title : title of article", ...
ratings: [
{ voter: "user1", score: 5 },
{ voter: "user2", score: 8 },
{ voter: "user3", score: 7 }
]
}
Sekarang Anda dapat menggabungkan ini dengan:
[ {$unwind: "$ratings"},
{$group : {_id : "$ratings.voter", averageScore: {$avg:"$ratings.score"} } }
]
Tapi contoh ini terstruktur seperti yang Anda gambarkan akan terlihat seperti ini:
{ title : title of article", ...
ratings: {
user1: 5,
user2: 8,
user3: 7
}
}
atau bahkan ini:
{ title : title of article", ...
ratings: [
{ user1: 5 },
{ user2: 8 },
{ user3: 7 }
]
}
Bahkan jika Anda bisa $unwind
ini, tidak ada yang perlu dikumpulkan di sini. Kecuali Anda mengetahui daftar lengkap semua kemungkinan kunci (pengguna), Anda tidak dapat berbuat banyak dengan ini. [*]
Skema DB relasional analog dengan apa yang Anda miliki adalah:
CREATE TABLE T (
user1: integer,
user2: integer,
user3: integer
...
);
Bukan itu yang akan dilakukan, sebaliknya kami akan melakukan ini:
CREATE TABLE T (
username: varchar(32),
score: integer
);
dan sekarang kita agregat menggunakan SQL:
select username, avg(score) from T group by username;
Ada permintaan peningkatan untuk MongoDB yang memungkinkan Anda melakukan ini dalam kerangka kerja agregasi di masa mendatang - kemampuan untuk memproyeksikan nilai ke kunci ke sebaliknya. Sementara itu, selalu ada peta/pengurangan.
[*] Ada cara yang rumit untuk melakukan ini jika Anda mengetahui semua kunci unik (Anda dapat menemukan semua kunci unik dengan metode yang mirip dengan ini) tetapi jika Anda mengetahui semua kunci, Anda sebaiknya menjalankan urutan kueri dari form db.articles.find({"ratings.user1":{$exists:true}},{_id:0,"ratings.user1":1})
untuk setiap penggunaX yang akan mengembalikan semua peringkat mereka dan Anda dapat menjumlahkan dan membuat rata-ratanya dengan cukup sederhana daripada melakukan proyeksi yang sangat kompleks yang diperlukan kerangka kerja agregasi.