Cara terbaik untuk menyimpan tanggal / waktu di mongodb

177

Saya telah melihat menggunakan string, cap waktu integer dan objek datong mongo.

xrado
sumber

Jawaban:

200

Cara terbaik adalah menyimpan objek Tanggal JavaScript asli , yang dipetakan ke objek Tanggal asli 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") }

Jenis asli mendukung seluruh jajaran metode yang berguna luar kotak, yang dapat Anda gunakan dalam pekerjaan pengurangan peta Anda, misalnya.

Jika perlu, Anda dapat dengan mudah mengkonversi Dateobjek ke dan dari Unix cap waktu 1) , menggunakan getTime()metode dan Date(milliseconds)konstruktor, masing-masing.

1) Sebenarnya, cap waktu Unix diukur dalam detik . Objek Tanggal JavaScript mengukur dalam milidetik sejak zaman Unix.

Niels van der Rest
sumber
9
Bagaimana itu akan disimpan dalam DB? Sebagai objek datong mongo?
Thilo
2
@ Thilo: MongoDB tidak memiliki objek 'datetime' khusus sejauh yang saya tahu. Ini menggunakan tipe tanggal JavaScript, yang disimpan dalam bentuk BSON.
Niels van der Rest
1
@ Thilo: Benar, pada dasarnya itu adalah representasi BSON dari objek JavaScript Date. Ini adalah integer 64-bit yang menyimpan milidetik sejak zaman Unix dan mendukung (sebagian besar?) Metode dari spesifikasi JavaScript .
Niels van der Rest
1
@AboozarRajabi The 389dan 240adalah milidetik dari cap waktu. Format Zdalam string memberi tahu MongoDB bahwa cap waktu yang Anda berikan adalah dalam UTC. Jika Anda kemudian membacanya kembali, aplikasi Anda mungkin mengubahnya ke zona waktu lokal Anda , sehingga sepertinya waktu telah berubah. Tetapi waktunya masih sama, hanya ditafsirkan dari perspektif zona waktu yang berbeda. Misalnya 12:50:42Zdan 13:50:42+01:00mewakili momen yang sama dalam waktu.
Niels van der Rest
5
@AboozarRajabi Secara umum Anda tidak ingin khawatir tentang bagaimana itu disimpan, selama input awal sudah benar. Jika 21:56:03+01:00sekarang di CET dan Anda masukkan new Date(), maka MongoDB mungkin mewakili sebagai 20:56:03Z. Tetapi ketika Anda membacanya kembali dan menampilkannya di aplikasi Anda menggunakan pengaturan zona waktu lokal (CET), itu akan membacanya 21:56:03lagi.
Niels van der Rest
53

Satu datestamp sudah ada di objek _id, mewakili waktu insert

Jadi, jika waktu memasukkan adalah yang Anda butuhkan, sudah ada di sana:

Masuk ke shell 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

Buat database Anda dengan memasukkan item

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

Mari kita buat database itu seperti sekarang ini

> use penguins
switched to db penguins

Dapatkan kembali baris:

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

Dapatkan setiap baris dalam format yyyy-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

Jika itu satu-liner membingungkan Anda, saya memiliki langkah-langkah tentang cara kerjanya di sini: https://stackoverflow.com/a/27613766/445131

Eric Leschinski
sumber
18
Tetapi ini adalah cap waktu ketika dokumen disimpan di db, kadang-kadang Anda ingin menyimpan tanggal dan waktu yang tidak terkait dengan tanggal penyisipan.
Yuval A.
1
Jika database Anda benar-benar cepat dan dua dokumen disimpan dalam milidetik yang sama .. apakah dokumen-dokumen itu sama _id?
Redsandro
10
@Redandro tidak, tetapi berpotensi mereka dapat memiliki hasil yang sama _id.getTimestamp().
kmiyashiro
@kmiyashiro, apakah Anda tahu cara menyortir berdasarkan stempel waktu itu?
ledlogic
1
Nevermind, sort ((dibuat pada: -1); adalah pendekatan untuk digunakan dari stackoverflow.com/questions/28599237/…
ledlogic