10

I'm loading some dates into mongodb using pymongo. Because pymongo does automatic conversions to BSON, I'm working with datetime's datetime.strptime function to turn input strings like "12/04/2013" into Date objects like so:

>>> datetime.datetime.strptime("12/04/2013",'%m/%d/%Y')
datetime.datetime(2013, 12, 4, 0, 0)

So that they can be searchable using standard mongo queries.

My problem is: I would also like to represent that I do not know what date something is in a way equivalent to None, so that I can do None null-tests on it. I realize I could just put this date very far in the past or future with a try-catch block for entering '' or None, but this is hacky thinking and I'd rather use a proper None-type to represent what is actually a None.

How can I enter a None datetime?

Mittenchops
  • 18,633
  • 33
  • 128
  • 246
  • 3
    Why not use `None` directly instead of a hypothetical "`None`-ish" datetime object? – Tim Pietzcker Dec 04 '13 at 21:58
  • Well, I'm kind of new to mongodb modeling, but I think then I would have inconsistent types in my BSON collection---some would be Date() objects, and others would be None. I'd rather they all be Date() types, some with a None value, others with date values. Not sure, maybe this is actually how this is done? – Mittenchops Dec 04 '13 at 22:01
  • `None` is a singleton. It has its own type (`NoneType`) precisely for this reason - to provide a universal "Value does not exist", as opposed to "value is empty". And "does not exist" is independent of type. I don't have a clue about MongoDB, so that may in fact be a problem (my question was serious). – Tim Pietzcker Dec 04 '13 at 22:04
  • Yeah, I'm not completely sure myself, new to doing date queries with mongo. I am hoping you're right, but wanted to check with internets. Zero-like nullsets are a pretty sweet invention and all. – Mittenchops Dec 04 '13 at 22:17

2 Answers2

8

When you search MongoDB null and missing values are equivalent.

> db.foo.insert({a: null})
> db.foo.insert({})
db.foo.find({a: null}, {_id: 0})
{ "a" : null }
{  }

It works the same way with pymongo:

>>> [doc for doc in pymongo.MongoClient().test.foo.find({'a': None}, {'_id': 0})]
[{u'a': None}, {}]

So None seems to be a good choice. It is consistent with Python semantics, it plays nice with default behavior of dict.get method and maps intuitively to MongoDB types when using Python driver.

zero323
  • 322,348
  • 103
  • 959
  • 935
1

MongoDB is a NoSQL database, meaning that you can make interesting data models.

http://docs.mongodb.org/manual/core/data-modeling-introduction/

Each document in your collection does not need to have the same set of field names. If you do not know the date, you may simply leave it out. Your application code can easily check the existence of of the timestamp when you want to retrieve the document

import pymongo
import datetime

mclient = pymongo.MongoClient()
mclient.test.example.insert({'Name': "Orange"})
mclient.test.example.insert({'Name': "Lemon", 'timestamp':datetime.datetime.now()})
for document in mclient.test.example.find():
    if "timestamp" in document:
        print document
Dan Cramer
  • 685
  • 1
  • 9
  • 14
bauman.space
  • 1,993
  • 13
  • 15