आपने सभी चरणों को लिखा है, लेकिन यहाँ बात यह है कि एक से दूसरे में कोई संबंध नहीं है, अर्थात पूर्व सेटअप में किए गए परिवर्तन अगले चरणों में दिखाई नहीं दे रहे हैं। कुछ मुद्दे :
{$sort: {$dateFromString:{time: 1}}} // You can't use `$dateFromString` in sort stage. Also syntax of `$dateFromString` is incorrect.
आइए मान लें कि अगर यह काम करता है (यह नहीं होगा लेकिन मान लें) आप वास्तव में time
परिवर्तित नहीं कर रहे हैं $group
. में बाद में उपयोग के लिए परिवर्तित समय को एक चर में संग्रहीत करना और संग्रहीत करना या और नीचे के चरण। तो आपको इसे $addFields
. का उपयोग करके संबंधित दस्तावेज़ में एक चर में संग्रहीत करने की आवश्यकता है या $project
. मैं और नीचे नहीं गया, लेकिन आप नीचे दी गई क्वेरी को आज़मा सकते हैं:
प्रश्न:
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" }
}
])
परीक्षा : mongoplayground
संदर्भ : aggregation-pipeline
नोट : यह क्वेरी "time_difference" :null
पहले दस्तावेज़ के लिए, लेकिन अगर इसकी आवश्यकता हो तो इसे initialValue
. में आज़माएं :docObj: [ {$mergeObjects :[ { $arrayElemAt: [ "$docs", 0 ] }, { "time_difference" :null } ] ]
. साथ ही, मैं $match
. का उपयोग करके इस ऑपरेशन को संग्रह में कुछ दस्तावेज़ों तक सीमित करने का सुझाव दूंगा पहले चरण के रूप में, सभी दस्तावेजों पर इस प्रश्न को करने के बजाय
{
$group: { _id: "", docs: { $push: "$$ROOT" } }
}
जब यह विशाल डेटासेट के साथ संपूर्ण संग्रह पर किया जाएगा तो यह अपने आप में एक बहुत बड़ी बात होगी।