Je hebt alle fasen geschreven, maar het punt hier is dat er geen relatie is tussen de ene naar de andere, betekent dat wijzigingen die zijn aangebracht bij eerdere instellingen niet worden weerspiegeld in de volgende stappen. Paar problemen:
{$sort: {$dateFromString:{time: 1}}} // You can't use `$dateFromString` in sort stage. Also syntax of `$dateFromString` is incorrect.
Laten we aannemen dat als het werkte (het zal niet anders zijn dan aannemen) dat je niet echt time
converteert &geconverteerde tijd opslaan in een variabele voor later gebruik in $group
of verder naar beneden stadia. U moet het dus opslaan in een variabele in het respectieve document met behulp van $addFields
of $project
. Ik ben niet verder gegaan, maar je kunt onderstaande vraag proberen:
Vraag:
db.collection.aggregate([
/** sort on `time` field */
{ $sort: { time: 1 } },
/** Convert string format of `time` field to milliseconds & store to `convertedTime` field for each doc */
{ $addFields: { convertedTime: { $toLong: { $dateFromString: { dateString: "$time" } } } } },
/** Group without condition to push all documents into `docs` array */
{
$group: { _id: "", docs: { $push: "$$ROOT" } }
},
/** re-creating `docs` array */
{
$project: {
_id: 0,
docs: {
$reduce: {
input: { $slice: [ "$docs", 1, { $size: "$docs" } ] }, /** Pick `docs` array without first element for iteration */
initialValue: { docObj: [ { $arrayElemAt: [ "$docs", 0 ] } ], previousTime: { $arrayElemAt: [ "$docs.convertedTime", 0 ] } },
in: {
docObj: { $concatArrays: [ "$$value.docObj", [
{ $mergeObjects: [ "$$this", { time_difference: { $divide: [ { $subtract: [ "$$this.convertedTime", "$$value.previousTime" ] }, 1000 ] } } ] }
]
]
},
previousTime: "$$this.convertedTime" // Store current doc's time to `previousTime` to utilize for next record
}
}
}
}
},
{
$unwind: { path: "$docs.docObj" }
},
/** Remove additionally added field */
{
$project: { "docs.docObj.convertedTime": 0 }
},
/** Replace root of the doc with `docs.docObj` */
{
$replaceRoot: { newRoot: "$docs.docObj" }
}
])
Test : mongoplayground
Ref: aggregation-pipeline
Opmerking: Deze zoekopdracht zou "time_difference" :null
. niet toevoegen voor het eerste document, maar voor het geval dat het nodig is, probeer dit in initialValue
:docObj: [ {$mergeObjects :[ { $arrayElemAt: [ "$docs", 0 ] }, { "time_difference" :null } ] ]
. Ik zou ook willen voorstellen om deze bewerking te beperken tot bepaalde documenten in de verzameling met behulp van $match
als eerste fase, in plaats van deze query op alle documenten te doen, veroorzaken
{
$group: { _id: "", docs: { $push: "$$ROOT" } }
}
zelf zal een enorm ding zijn als het wordt gedaan op de hele verzameling met een enorme dataset.