Search code examples
mongodbmongodb-querymongo-c-drivermongo-cxx-driver

mongoc driver: how to query based on ISOdate?


I have a simple query that worked on mongodb shell:

db.collection.find({"date": {$lt: ISODate("2015-11-03T00:00:00Z")} })

very simple, just trying to find any record that has date before 2015-11-03. Now i want to translate to similar code in mongoc driver, i have following code that doesn't work:

query = BCON_NEW (
   "date", "{", "$lt", "2015-11-03T00:00:00Z", "}", "}");    
cursor = mongoc_collection_find (collection, MONGOC_QUERY_NONE, 0, 0, 0, query, NULL, NULL);

anyone knows the correct way to write in mongoc? I have looked through mongoc.org, no related example there.


Solution

  • BCON is incredibly touchy, but it is super useful once you get the hang of it

    First of all, you need to apply a BCON type to anything that isn't a key and carefully count your braces. Every opening brace needs a closing brace. BCON_NEW itself will handle the very first and very last brace in the document.

    query = BCON_NEW ("date", "{", "$lt", "2015-11-03T00:00:00Z", "}", "}"); 
                        ^             ^              ^                  ^
                        |             |              |                  |
    keys ------------------------------              |                  |
    value --------------------------------------------                  |
    brace that shouldn't exist ------------------------------------------
    

    this page will tell you perspective types you might want to choose for your value

    https://github.com/mongodb/libbson/blob/master/src/bson/bcon.c#L214-L292

    Your collection says it holds an ISODate, so you're going to want the BCON_DATE_TIME type.

    Switch the type and get rid of that extra trailing closing brace and your query probably needs to look like this.

    query = BCON_NEW ("date", "{", "$lt", BCON_DATE_TIME("2015-11-03T00:00:00Z"), "}");