Search code examples
pythonmongodbpymongomongodb-querycompound-index

Query compound _id for time range in MongoDB using PyMongo


I have a collection in which the _ids are compound of a time and an string (yeah, I know it's bad but... it was like that when I arrived). One record in that collection looks like:

{
  "_id": {
    "my_string": "Foo",
    "my_time": new Date("2014-12-19T12:38:00-0500")
  },
  "field1": 60,
  "field2": 17,
}

Basically, I'm trying to figure out a query which would give me the records where _id.my_string is Foo and _id.my_time is between time1 and time2

Can I use $and to build a query dict querying different parts of the compound _id?

This returns 0 records:

my_collection.find(
    {
        '_id': {
            'my_string': 'Foo',
            '$and': [
                {'my_time': {'$gte': datetime.datetime(...)}},
                {'my_time': {'$lte': datetime.datetime(...)}},
            ]
        }
    }
)

So does this this:

 my_collection.find(
    {'$and': [
        {'_id':
            {
                'my_string': "Foo"
                'my_time': {'$lte': datetime.datetime(...)}
            }
         },
        {'_id':
            {
                'my_string': "Foo",
                'my_time': {'$gte': datetime.datetime(...)}
            }
         },
        ]
     }

Just in case you haven't noticed, I'm a real newbie when it comes to MongoDB.

Thank you in advance!


Solution

  • my_collection.find(
        {
            '$and' :
                [
                    {'_id.my_string': 'Foo'},
                    {'_id.my_time' : {'$gte': datetime.datetime(...), '$lte': datetime.datetime(...)}},
                ]
            }
        }
        )
    

    You do not need to use $and for this query.

    The following query can be written as:

    my_collection.find(
        {
            '_id.my_string': 'Foo',
            '_id.my_time' : 
            {
                '$gte': datetime.datetime(...), 
                '$lte': datetime.datetime(...)
            }
        }
        )