Karena pertanyaan Anda saat ini tidak jelas, saya sangat berharap maksud Anda bahwa Anda ingin menentukan dua Site
kunci dan 2 Software
kunci karena itu adalah jawaban yang bagus dan sederhana yang dapat Anda tambahkan ke fase $match Anda seperti pada:
{$match: {
group_id: "20ea74df4f7074b33b520000",
tracked_item_name: {$in: ['Twitter', 'Facebook', 'Word', 'Excel' ] }
}},
Dan kita semua bisa bersorak dan bahagia;)
Namun jika pertanyaan Anda adalah sesuatu yang lebih jahat seperti, mendapatkan 2 Site
teratas dan Software
entri dari hasil dengan durasi, maka kami berterima kasih banyak untuk menelurkan kekejian . ini .
Peringatan:
Jarak tempuh Anda mungkin berbeda pada apa yang sebenarnya ingin Anda lakukan atau apakah ini akan meledak dengan ukuran hasil Anda. Tapi berikut ini sebagai contoh dari apa yang Anda inginkan:
db.collection.aggregate([
// Match items first to reduce the set
{$match: {group_id: "20ea74df4f7074b33b520000" }},
// Group on the types and "sum" of duration
{$group: {
_id: {
tracked_item_type: "$tracked_item_type",
tracked_item_name: "$tracked_item_name"
},
duration: {$sum: "$duration"}
}},
// Sort by type and duration descending
{$sort: { "_id.tracked_item_type": 1, duration: -1 }},
/* The fun part */
// Re-shape results to "sites" and "software" arrays
{$group: {
_id: null,
sites: {$push:
{$cond: [
{$eq: ["$_id.tracked_item_type", "Site" ]},
{ _id: "$_id", duration: "$duration" },
null
]}
},
software: {$push:
{$cond: [
{$eq: ["$_id.tracked_item_type", "Software" ]},
{ _id: "$_id", duration: "$duration" },
null
]}
}
}},
// Remove the null values for "software"
{$unwind: "$software"},
{$match: { software: {$ne: null} }},
{$group: {
_id: "$_id",
software: {$push: "$software"},
sites: {$first: "$sites"}
}},
// Remove the null values for "sites"
{$unwind: "$sites"},
{$match: { sites: {$ne: null} }},
{$group: {
_id: "$_id",
software: {$first: "$software"},
sites: {$push: "$sites"}
}},
// Project out software and limit to the *top* 2 results
{$unwind: "$software"},
{$project: {
_id: 0,
_id: { _id: "$software._id", duration: "$software.duration" },
sites: "$sites"
}},
{$limit : 2},
// Project sites, grouping multiple software per key, requires a sort
// then limit the *top* 2 results
{$unwind: "$sites"},
{$group: {
_id: { _id: "$sites._id", duration: "$sites.duration" },
software: {$push: "$_id" }
}},
{$sort: { "_id.duration": -1 }},
{$limit: 2}
])
Sekarang hasilnya adalah *tidak persis kumpulan hasil bersih yang ideal tetapi itu adalah sesuatu yang dapat dikerjakan secara terprogram, dan lebih baik daripada memfilter hasil sebelumnya dalam satu lingkaran. (Data saya dari pengujian)
{
"result" : [
{
"_id" : {
"_id" : {
"tracked_item_type" : "Site",
"tracked_item_name" : "Digital Blasphemy"
},
"duration" : 8000
},
"software" : [
{
"_id" : {
"tracked_item_type" : "Software",
"tracked_item_name" : "Word"
},
"duration" : 9540
},
{
"_id" : {
"tracked_item_type" : "Software",
"tracked_item_name" : "Notepad"
},
"duration" : 4000
}
]
},
{
"_id" : {
"_id" : {
"tracked_item_type" : "Site",
"tracked_item_name" : "Facebook"
},
"duration" : 7920
},
"software" : [
{
"_id" : {
"tracked_item_type" : "Software",
"tracked_item_name" : "Word"
},
"duration" : 9540
},
{
"_id" : {
"tracked_item_type" : "Software",
"tracked_item_name" : "Notepad"
},
"duration" : 4000
}
]
}
],
"ok" : 1
}
Jadi Anda melihat Anda mendapatkan 2 Site
teratas dalam larik, dengan 2 Software
teratas item tertanam di masing-masing. Agregasi itu sendiri, tidak dapat menjelaskan lebih jauh, karena kita perlu menggabungkan kembali item yang kami pisahkan untuk melakukan ini, dan belum ada operator yang dapat kami gunakan untuk melakukan tindakan ini.
Tapi itu menyenangkan. Bukan semua cara dilakukan, tetapi sebagian besar cara, dan menjadikannya sebagai respons 4 dokumen akan menjadi kode yang relatif sepele. Tapi kepalaku sudah sakit.