La mejor manera de almacenar fecha / hora en mongodb

Respuestas:

200

La mejor manera es almacenar objetos de fecha JavaScript nativos , que se asignan a objetos de fecha nativos BSON .

> db.test.insert({date: ISODate()})
> db.test.insert({date: new Date()})
> db.test.find()
{ "_id" : ObjectId("..."), "date" : ISODate("2014-02-10T10:50:42.389Z") }
{ "_id" : ObjectId("..."), "date" : ISODate("2014-02-10T10:50:57.240Z") }

El tipo nativo admite una amplia gama de métodos útiles. para usar, que puede usar en sus trabajos de reducción de mapas, por ejemplo.

Si lo necesita, puede convertir fácilmente Dateobjetos hacia y desde las marcas de tiempo Unix 1) , utilizando el getTime()método y el Date(milliseconds)constructor, respectivamente.

1) Hablando estrictamente, la marca de tiempo Unix se mide en segundos . El objeto Fecha de JavaScript se mide en milisegundos desde la época de Unix.

Niels van der Rest
fuente
9
¿Cómo se almacenará eso en la base de datos? Como un objeto mongo datetime?
Thilo
2
@Thilo: MongoDB no tiene ningún objeto especial 'datetime' hasta donde yo sé. Utiliza el tipo de fecha de JavaScript, que se almacena en forma BSON.
Niels van der Rest
1
@Thilo: Correcto, esa es básicamente la representación BSON de un objeto Fecha de JavaScript. Es un entero de 64 bits que almacena los milisegundos desde la época de Unix y admite (¿la mayoría?) De los métodos de la especificación de JavaScript .
Niels van der Rest
1
@AboozarRajabi El 389y 240son los milisegundos de la marca de tiempo. El formatoZ en cadena le dice a MongoDB que la marca de tiempo que proporcionó está en UTC. Si luego lo vuelve a leer, su aplicación probablemente lo convierta a su zona horaria local , haciendo que parezca que la hora ha cambiado. Pero el tiempo sigue siendo el mismo, solo se interpreta desde una perspectiva de zona horaria diferente. Por ejemplo 12:50:42Zy 13:50:42+01:00representan el mismo momento en el tiempo.
Niels van der Rest
55
@AboozarRajabi En general, no debe preocuparse por cómo se almacena, siempre que la entrada inicial sea correcta. Si 21:56:03+01:00ahora está en CET e inserta new Date(), MongoDB podría representarlo como 20:56:03Z. Pero cuando lo lea de nuevo y lo muestre en su aplicación utilizando la configuración de zona horaria local (CET), volverá a leer 21:56:03.
Niels van der Rest
53

Ya hay un sello de fecha en el objeto _id, que representa la hora de inserción

Entonces, si el tiempo de inserción es lo que necesita, ya está allí:

Inicie sesión en mongodb shell

ubuntu@ip-10-0-1-223:~$ mongo 10.0.1.223
MongoDB shell version: 2.4.9
connecting to: 10.0.1.223/test

Crea tu base de datos insertando elementos

> db.penguins.insert({"penguin": "skipper"})
> db.penguins.insert({"penguin": "kowalski"})
> 

Hagamos de esa base de datos la que estamos ahora

> use penguins
switched to db penguins

Recupere las filas:

> db.penguins.find()
{ "_id" : ObjectId("5498da1bf83a61f58ef6c6d5"), "penguin" : "skipper" }
{ "_id" : ObjectId("5498da28f83a61f58ef6c6d6"), "penguin" : "kowalski" }

Obtenga cada fila en aaaa-MM-dd HH: mm: formato ss:

> db.penguins.find().forEach(function (doc){ d = doc._id.getTimestamp(); print(d.getFullYear()+"-"+(d.getMonth()+1)+"-"+d.getDate() + " " + d.getHours() + ":" + d.getMinutes() + ":" + d.getSeconds()) })
2014-12-23 3:4:41
2014-12-23 3:4:53

Si esa última frase te confunde, tengo un tutorial sobre cómo funciona eso aquí: https://stackoverflow.com/a/27613766/445131

Eric Leschinski
fuente
18
Pero es la marca de tiempo para cuando el documento se guardó en la base de datos, a veces desea almacenar fechas y horas no relacionadas con la fecha de inserción.
Yuval A.
1
Si su base de datos es realmente rápida y dos documentos se almacenan en el mismo milisegundo ... ¿esos documentos tienen lo mismo _id?
Redsandro
10
@Redsandro no, pero potencialmente podrían tener el mismo resultado _id.getTimestamp().
kmiyashiro
@kmiyashiro, ¿sabrías cómo ordenar según esa marca de tiempo?
ledlogic
1
No importa, ordenar ({createdOn: -1); es el enfoque a usar desde stackoverflow.com/questions/28599237/…
ledlogic