Entonces, básicamente estoy tratando de implementar una consulta que es fácil en lenguajes de programación funcionales, pero parece que no puedo hacer que funcione en una consulta de Mongo.
El término "estadístico" que encontré para esto es "Max Hold": https://chiptools.readthedocs.io/en/latest/max_hold.html
map-reduce (no puedo encontrar cómo mantener valores intermedios dentro de los documentos que estoy pasando)aporte:
[ { "key": 1, "value": 10 } , { "key": 2, "value": 11 } , { "key": 3, "value": 9 } , { "key": 4, "value": 12 } ]producción:
[ { "key": 1, "value": 10, "prefix_max_val": 10 } , { "key": 2, "value": 11, "prefix_max_val": 11 } , { "key": 3, "value": 9, "prefix_max_val": 11 } , { "key": 4, "value": 12, "prefix_max_val": 12 } ] En Javascript (o cualquier otro lenguaje de programación de propósito general) haría algo como esto (que es un algoritmo de tiempo lineal):
function(input) { let result = []; let curr_max = 0; for (let i=0; i<input.length; i++) { result[i] = Math.max(curr_max, input[i]); curr_max = result[i]; } return result; }Gracias :)
Con MongoDB 5.0 puedes usar setWindowFields
db.collection.aggregate([ { $setWindowFields: { sortBy: { key: 1 }, output: { prefix_max_val: { $max: "$value", window: { documents: ['unbounded', 'current'] } } } } } ])Si aún no ejecuta la versión 5.0 de MongoDB, intente con esta:
db.collection.aggregate([ { $sort: { key: 1 } }, { $group: { _id: null, data: { $push: "$$ROOT" } } }, { $set: { data: { $reduce: { input: { $range: [0, { $size: "$data" }] }, initialValue: [], in: { $concatArrays: ["$$value", [ { $mergeObjects: [ { prefix_max_val: { $max: { $slice: ["$data.value", { $add: ["$$this", 1] }] } } }, { $arrayElemAt: ["$data", "$$this"] }] }] ] } } } } }, { $unwind: "$data" }, { $replaceWith: "$data" } ])Para encontrar el valor máximo, puede usar el siguiente código: -
db.collection.aggregate({ $group : { _id: null, prefix_max_val: { $max : "$value" }}});