Penafian
Sebelum membaca sisa jawabannya, harap baca https://docs. mongodb.com/manual/core/aggregation-pipeline-limits/ Dokumen yang dihasilkan dalam pertanyaan diharapkan memiliki larik dari semua dokumen yang termasuk dalam kelompok usia tertentu.Ukuran larik tersebut tidak boleh melebihi 16 MB , jadi kode di bawah ini hanya akan berfungsi untuk kumpulan dokumen kecil yang sangat kecil.
Kode:
db.collection.aggregate([
{ $sort: { age: 1 } },
{ $group: {
_id: null,
ages: { $push: "$age" }
} },
{ $addFields: {
ranges: { $reduce: {
input: { $range: [ 1, { $size: "$ages" }, 1 ] },
initialValue: [ [ { $arrayElemAt: [ "$ages", 0 ] } ] ],
in: { $cond: {
if: { $gt: [
{ $subtract: [ { $arrayElemAt: [ "$ages", "$$this" ] }, { $arrayElemAt: [ "$ages", { $subtract: [ "$$this", 1 ] } ] } ] },
2
] },
then: { $concatArrays: [ "$$value", [ [ { $arrayElemAt: [ "$ages", "$$this" ] } ] ] ] },
else: { $concatArrays: [
{ $slice: [ "$$value" , { $subtract: [ { $size: "$$value" }, 1 ] } ] },
[ { $concatArrays: [
{ $arrayElemAt: [ { $slice: [ "$$value" , -1 ] }, 0 ] } ,
[ { $arrayElemAt: [ "$ages", "$$this" ] } ]
] } ]
] }
} }
} }
} },
{ $unwind: "$ranges" },
{ $lookup: {
from: "collection",
localField: "ranges",
foreignField: "age",
as: "group"
} },
{ $project: { _id: 0, group: 1 } }
])
Bagian yang mungkin memerlukan sedikit penjelasan adalah cara menghitung kelompok umur.
Untuk itu, kami mendapatkan semua usia menggunakan $group ke dalam satu larik lalu $addFields "rentang" - larik 2D kelompok usia dengan jarak antara orang tertua dalam kelompok yang lebih muda dan orang termuda dalam kelompok yang lebih tua lebih dari 2 tahun.
Array dihitung menggunakan $reduce dari $range array indeks dari segala usia tetapi pertama, yang menuju ke nilai awal.
Ekspresi pengurangan adalah $cond yang menghitung perbedaan antara saat ini dan sebelumnya ($subtract ) elemen larik segala usia.
Jika lebih besar dari 2, kelompok usia baru ditambahkan menggunakan $concatArrays . Jika tidak, usia ditambahkan ke grup tertua menggunakan $slice untuk mendorong ke grup terakhir dalam larik rentang dan $setUnion untuk menghilangkan duplikat.
Saat kelompok usia dihitung, kami $lookup koleksi yang sama berdasarkan usia untuk mengelompokkannya dalam larik "grup".