Reputation: 2458
It may be really simple, but the obvious is elusive at the moment in Ruby land.
How do I insert document field value as ISODate and NOT a string with Ruby MongoDB driver? When I query a collection inside the MongoDB shell, I want the timestamp to be an ISODate object:
{
"_id": ObjectId("570348904b3833000addcd67"),
"timestamp": ISODate("2016-04-04T21:23:52.058Z")
}
And NOT:
{
"_id": ObjectId("570348904b3833000addcd67"),
"timestamp": "2016-04-04T21:23:52.058Z" // or ms since epoch
}
Please don't suggest I use ms|s since epoch. It's not a solution here.
I've tried...
logs = []
t = Time.at(1448064510963.fdiv(1000))
mongo_hash['timestamp'] = t # --> String
mongo_hash[:timestamp] = t # --> String
mongo_hash['timestamp'] = t.to_datetime # --> Weird Date String
mongo_hash['timestamp'] = t.to_date # --> String without time
logs << mongo_hash
I'm pushing mongo_hash
into an array that's passed into insert_many
.
mongo_client[:logs].insert_many(logs)
...and what I get in MongoDB 3.0.x is a string for the timestamp using Ruby Mongo driver v2.2.4...
{
"_id": ObjectId("573107ac4f5bd9ac14920bb0"),
"timestamp": "2015-11-20T11:59:43.127-08:00"
}
Piece of cake in JS/Python... why so weird, Ruby? Whyyyy?
Upvotes: 3
Views: 3123
Reputation: 434735
I couldn't find any documentation on this but if you look at the official examples, you'll see this:
result = client[:restaurants].insert_one({
#...
grades: [
{
date: DateTime.strptime('2014-10-01', '%Y-%m-%d'),
grade: 'A',
score: 11
},
#...
]
#...
})
That would suggest that you can use simple DateTime
instances to insert times into MongoDB. So what happens if we try that? Well:
irb> mongo[:pancakes].insert_one(:kind => 'blueberry', :created_at => DateTime.now)
and then in MongoDB:
> db.pancakes.find()
{ "_id" : ..., "kind" : "blueberry", "created_at" : ISODate("2016-05-15T17:44:12.096Z") }
The ISODate
that we want is there.
Then if we pretend we're in Rails:
irb> require 'active_support/all' # To get to_datetime
irb> mongo[:pancakes].insert_one(:kind => 'banana', :created_at => '2016-05-15T06:11:42.235Z'.to_datetime)
we get this inside MongoDB:
> db.pancakes.find()
{ "_id" : ObjectId("5738b56cf638ccf407c71ef5"), "kind" : "blueberry", "created_at" : ISODate("2016-05-15T17:44:12.096Z") }
{ "_id" : ObjectId("5738b74ef638ccf4da4c2675"), "kind" : "banana", "created_at" : ISODate("2016-05-15T06:11:42.235Z") }
ISODate
s again.
I'm using version 2.2.5 of the official Ruby driver here.
Upvotes: 3