Skip to content
Advertisement

MongoDB/Python – Date in collection (to use for query)

I just started using mongoDB (Version 3.6.8) today, and I like it.

I was reading that it should be possible to have a date object directly in the database, but I can’t get it to work.

Also I was wondering if it is the best solution or if I should just store my dates as “Epoch millis” instead?

I am trying to use use the $dateFromString keyword which should work but i receive this error:

bson.errors.InvalidDocument: key '$dateFromString' must not start with '$'

My code looks like this:

from datetime import date
import pymongo

dbcli   = pymongo.MongoClient('mongodb://192.168.1.8:27017')
db      = dbcli['washbase']
col     = db['machine']

def conv(dato):
    return {
            '$dateFromString': {
                'dateString': dato,
                'format': '%Y-%m-%d',
                'timezone':'Europe/Copenhagen',
                }
            }
    
today = date.today().isoformat()

data = {
        'day': conv(today),
        'time':12,
        'room':'2B',
        }


col.insert_one(data)

The reason why I need something like a date-object in the database is because I want to do a conditional query on the data, so that the database only sends the data i require. So i expect to do something like this.

result = col.find(
        {
            'day' : {
                '$gt' : {
                    '$date' : '2020-01-01'
                    }
                }
            }
        )
for x in results:
    print(x)

But when I do this the app prints nothing.

Advertisement

Answer

The $dateFromString is an operator for MongoDB aggregations. An aggregation is a powerful way to create complex queries in MongoDB. Hence, this might not be what you need.

I would recommend storing the dates in the normal format. So your code should look something like this:

from datetime import date
import pymongo

dbcli   = pymongo.MongoClient('mongodb://192.168.1.8:27017')
db      = dbcli['washbase']
col     = db['machine']
    
today = date.today().isoformat()

data = {
        'day': today,
        'time':12,
        'room':'2B',
        }


col.insert_one(data)

If you are concerned about timezones, MongoDB stores each date in UTC by default, converting whatever timezone is specified in your date to UTC. When reading the dates, you can then convert them to whatever timezone you need.

EDIT: When writing your query, try using an actual date object. This converts the query date to an actual ISO date that the DB can understand.

col.find({'day': {'$gte': ISODate(date.today) }}) 

If you’re trying to find entries that fall within a date range, you can do something like:

col.find({'day': {'$gte': ISODate(date.today), '$lte': ISODate(date.today + 24 hours) }}) 
Advertisement