MongoDB
 sql >> Database >  >> NoSQL >> MongoDB

Ottenere un timestamp unix in pochi secondi da MongoDB ISODate durante l'aggregazione

Non sono sicuro del motivo per cui pensi di aver bisogno del valore in secondi anziché in millisecondi poiché generalmente entrambi i moduli sono validi e nella maggior parte delle implementazioni del linguaggio i millisecondi sono effettivamente preferiti. Ma in generale, cercare di costringerlo in una stringa è il modo sbagliato per aggirare il problema, e generalmente fai solo i conti:

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
        ]}
      ]
    }
  }}
])

Che ti restituisce un timestamp di epoch in secondi. Fondamentalmente derivato da quando un oggetto data BSON viene sottratto da un altro, il risultato è l'intervallo di tempo in millisecondi. L'utilizzo della data di epoca iniziale di "01-01-1970" comporta essenzialmente l'estrazione del valore dei millisecondi dal valore della data corrente. Il $divide l'operatore sostanzialmente elimina la parte dei millisecondi e il $mod esegue il modulo per implementare l'arrotondamento.

In realtà, è meglio che tu faccia il lavoro nella lingua nativa per la tua applicazione poiché tutte le date BSON verranno restituite lì come tipo "data/ora" nativo in cui puoi estrarre il valore del timestamp. Considera le basi di JavaScript nella shell:

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

In genere con l'aggregazione si desidera eseguire questo tipo di "matematica" su un valore di timestamp da utilizzare in qualcosa come l'aggregazione di valori all'interno di un periodo di tempo come un giorno. Ci sono operatori di data disponibili per il framework di aggregazione, ma puoi anche farlo nel modo matematico delle date:

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 }
    }}
])

Tale modulo sarebbe più tipico per emettere un timestamp arrotondato a un giorno e aggregare i risultati all'interno di tali intervalli.

Quindi il tuo scopo del framework di aggregazione solo per estrarre un timestamp non sembra essere l'utilizzo migliore o in effetti non dovrebbe essere necessario convertirlo in secondi anziché in millisecondi. Nel codice della tua applicazione è dove penso che dovresti farlo a meno che ovviamente non desideri effettivamente risultati per intervalli di tempo in cui puoi applicare la matematica della data come mostrato.

I metodi ci sono, ma a meno che tu non stia effettivamente aggregando, questa sarebbe l'opzione di prestazioni peggiori per la tua applicazione. Esegui invece la conversione nel codice.