sql >> Database >  >> NoSQL >> MongoDB

Moet het datetime-verschil berekenen voor het datetime-veld dat is opgeslagen in tekenreeksindeling in MongoDB

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.




  1. Bereikquery voor MongoDB-paginering

  2. MongoDB PHP:Hoe krijg ik ObjectId met een JSON-feed? (het is leeg)

  3. De drie A's van MongoDB-beveiliging - authenticatie, autorisatie en auditing

  4. MongoDB als een tijdreeksdatabase