Легкого пути нет.Вам нужно будет сгруппировать всю коллекцию в массив, для чего может потребоваться allowDiskUse для больших наборов данных с огромным влиянием на производительность.
db.collection.aggregate([
// count all documents
{ $group: {
_id: null,
cnt: { $sum: 1},
docs: { $push: "$$ROOT" }
} },
// add _batch field to group documents by
{ $project: {
_id: 0,
docs: { $map: {
// add a sequential number to each
input: { $zip: {
inputs: [ "$docs", { $range: [ 0, "$cnt" ] } ]
} },
as: "doc",
in: { $mergeObjects: [
{ $arrayElemAt: [ "$$doc", 0 ] },
// split it in batches by 4 based on the sequential number
{ _batch: { $cond: [
{ $eq: [ { $arrayElemAt: [ "$$doc", 1 ] }, 0 ] },
1,
{ $ceil: { $divide: [ { $arrayElemAt: [ "$$doc", 1 ] }, 4 ] } }
] } }
] }
} }
} },
{ $unwind: "$docs" },
{ $replaceRoot: { newRoot: "$docs" } },
// ensure original order, only if you need ItemRange as a string
{ $sort: { _id: 1 } },
// calculate averages per batch
{ $group: {
_id: "$_batch",
start: { $first: "$ItemName" }, // only if you need ItemRange as a string
end: { $last: "$ItemName" }, // only if you need ItemRange as a string
RatingAvg: {$avg: "$Rating"}
} },
// only if you need them in order
{ $sort: { _id: 1 } },
// calculate ItemRange, only if you need ItemRange as a string
{ $project: {
_id: 0,
ItemRange: { $concat: [ "$start", "-", "$end" ] },
RatingAvg: 1
} },
])
Не уверен насчет практического варианта использования, так как все средние значения изменятся при удалениинапример, первый документ.
В любом случае, если вам не нужен ItemRange в формате «FirstName-LastName» и вы можете использовать вместо номера пакета, вы можете пропустить 2 последних сортировки в памяти, что должно повысить производительность.