Najlepszy sposób na przechowywanie daty / czasu w mongodb

177

Widziałem użycie ciągów znaków, całkowitych znaczników czasu i obiektów daty i godziny mongo.

xrado
źródło

Odpowiedzi:

200

Najlepszym sposobem jest przechowywanie natywnych obiektów JavaScript Date , które są mapowane na natywne obiekty Date 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") }

Typ natywny obsługuje całą gamę przydatnych metod , których można używać na przykład w zadaniach redukcji map.

Jeśli potrzebujesz, możesz łatwo przekonwertować Dateobiekty na i ze znaczników czasu systemu Unix 1) , używając odpowiednio getTime()metody i Date(milliseconds)konstruktora.

1) Ściśle mówiąc, uniksowy znacznik czasu jest mierzony w sekundach . Obiekt JavaScript Date mierzy w milisekundach od epoki Uniksa.

Niels van der Rest
źródło
9
Jak to będzie przechowywane w bazie danych? Jako obiekt daty i godziny mongo?
Thilo,
2
@Thilo: MongoDB nie ma specjalnego obiektu „datetime”, o ile wiem. Używa typu JavaScript Date, który jest przechowywany w postaci BSON.
Niels van der Rest
1
@Thilo: Dobrze, to jest w zasadzie reprezentacja BSON obiektu Date JavaScript. Jest to 64-bitowa liczba całkowita, która przechowuje milisekundy od epoki Uniksa i obsługuje (większość?) Metod ze specyfikacji JavaScript .
Niels van der Rest
1
@AboozarRajabi 389i 240są milisekundami sygnatury czasowej. Znak Zw formacie ciągu informuje MongoDB, że podana sygnatura czasowa jest w czasie UTC. Jeśli później go przeczytasz, Twoja aplikacja prawdopodobnie przekonwertuje ją na lokalną strefę czasową, sprawiając wrażenie, że czas się zmienił. Ale czas jest wciąż ten sam, jest interpretowany tylko z innej perspektywy strefy czasowej. Na przykład 12:50:42Zi 13:50:42+01:00reprezentuj ten sam moment w czasie.
Niels van der Rest
5
@AboozarRajabi Generalnie nie chcesz przejmować się tym , jak jest przechowywany, o ile początkowe dane wejściowe są poprawne. Jeśli jest 21:56:03+01:00teraz w CET i wstawisz new Date(), to MongoDB może reprezentować to jako 20:56:03Z. Ale kiedy ponownie go przeczytasz i wyświetlisz w aplikacji przy użyciu lokalnych ustawień strefy czasowej (CET), zostanie 21:56:03ponownie odczytany .
Niels van der Rest
53

Jeden datownik znajduje się już w obiekcie _id, reprezentującym czas wstawiania

Więc jeśli potrzebujesz czasu wstawiania, już tam jest:

Zaloguj się do powłoki mongodb

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

Utwórz bazę danych, wstawiając elementy

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

Niech ta baza danych będzie tą, na której teraz jesteśmy

> use penguins
switched to db penguins

Przywróć wiersze:

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

Pobierz każdy wiersz w formacie rrrr-MM-dd HH: mm: 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

Jeśli ta ostatnia linijka cię zmyli, mam tutaj przewodnik, jak to działa: https://stackoverflow.com/a/27613766/445131

Eric Leschinski
źródło
18
Ale jest to sygnatura czasowa, kiedy dokument został zapisany w bazie danych, czasami chcesz przechowywać daty i godziny niezwiązane z datą wstawienia.
Yuval A.
1
Jeśli twoja baza danych jest naprawdę szybka, a dwa dokumenty są przechowywane w tej samej milisekundzie… czy te dokumenty mają to samo _id?
Redsandro
10
@Redsandro nie, ale potencjalnie mogą mieć ten sam wynik _id.getTimestamp().
kmiyashiro
@kmiyashiro, czy wiesz, jak sortować według tego znacznika czasu?
ledlogic
1
Nieważne, sort ({createdOn: -1); to podejście do użycia ze stackoverflow.com/questions/28599237/ ...
ledlogic