sql >> Database >  >> NoSQL >> MongoDB

Unix-tijdstempel in seconden uit MongoDB ISODate halen tijdens aggregatie

Ik weet niet zeker waarom je denkt dat je de waarde in seconden nodig hebt in plaats van milliseconden, aangezien beide vormen over het algemeen geldig zijn en in de meeste taalimplementaties de milliseconden eigenlijk de voorkeur hebben. Maar over het algemeen is het de verkeerde manier om dit in een string te dwingen, en over het algemeen doe je gewoon de wiskunde:

db.data.aggregate([
  { "$project": {
    "timestamp": {
      "$subtract": [
        { "$divide": [
            { "$subtract": [ "$md", new Date("1970-01-01") ] },
            1000
        ]},
        { "$mod": [
          { "$divide": [
              { "$subtract": [ "$md", new Date("1970-01-01") ] },
              1000
          ]},
          1
        ]}
      ]
    }
  }}
])

Dat geeft u een tijdstempel van een tijdperk in seconden. In principe afgeleid van wanneer een BSON-datumobject wordt afgetrokken van een ander, is het resultaat het tijdsinterval in milliseconden. Het gebruik van de initiële epochedatum van "1970/01/01" resulteert in het in wezen extraheren van de millisecondenwaarde uit de huidige datumwaarde. De $divide operator neemt in wezen het millisecondengedeelte weg en de $mod doet de modulo om afronding te implementeren.

Het is echter beter om het werk in de moedertaal voor uw toepassing te doen, aangezien alle BSON-datums daar worden geretourneerd als een native "date/datetime"-type waar u de tijdstempelwaarde kunt extraheren. Overweeg de basisprincipes van JavaScript in de shell:

var date = new Date()
( date.valueOf() / 1000 ) - ( ( date.valueOf() / 1000 ) % 1 )

Meestal wil je bij aggregatie dit soort "wiskunde" doen met een tijdstempelwaarde voor gebruik in zoiets als het aggregeren van waarden binnen een tijdsperiode zoals een dag. Er zijn datumoperators beschikbaar voor het aggregatieraamwerk, maar u kunt het ook op de datumberekening doen:

db.data.aggregate([
    { "$group": {
        "_id": {
          "$subtract": [
              { "$subtract": [ "$md", new Date("1970-01-01") ] },
              { "$mod": [
                  { "$subtract": [ "$md", new Date("1970-01-01") ] },
                  1000 * 60 * 60 * 24
              ]}
          ]
        },
        "count": { "$sum": 1 }
    }}
])

Die vorm zou gebruikelijker zijn om een ​​tijdstempel, afgerond op een dag, uit te zenden en de resultaten binnen die intervallen te aggregeren.

Dus uw bedoeling van het aggregatieraamwerk om alleen een tijdstempel te extraheren, lijkt niet het beste gebruik te zijn, of het zou zelfs niet nodig moeten zijn om dit om te zetten in seconden in plaats van milliseconden. In uw toepassingscode is waar ik denk dat u dat zou moeten doen, tenzij u natuurlijk resultaten wilt voor tijdsintervallen waarin u de datumberekening kunt toepassen zoals weergegeven.

De methoden zijn er, maar tenzij u daadwerkelijk aggregeert, zou dit de slechtste prestatie-optie voor uw toepassing zijn. Voer in plaats daarvan de conversie in code uit.




  1. MongoDB-zelfstudie voor beginners (volledige gids) - Leer MongoDB in 15 minuten

  2. Hoe Robomongo te verbinden met MongoDB

  3. Hoe update/upsert ik een document in Mongoose?

  4. Unit testen met MongoDB