Search code examples
mongodbmongodb-querymongo-c-driver

mongo c driver: how to query documents with "_id" in a list?


I have a db with huge amount of documents, and I only want to query documents with "_id" from a list. I searched online for a few hours, and did not find anything really working, so I post my question here. Thank you very much for any help!

in MongoDB command line environment, it is very easy to achieve what I want. The query command, for example, is as follows:

db.collection.find({"_id":{$in:[ObjectId("595320c208b0c52a8b37c151"), ObjectId("595320c208b0c52a8b37c152"), ObjectId("595320c208b0c52a8b37c153")]}})

Using mongoc driver, to retrieve document by id directly is simple too. Below is an example:

bson_t *qry = bson_new();
BSON_APPEND_OID(qry, "_id", &oid);
mongoc_cursor_t *cursor = mongoc_collection_find(col, MONGOC_QUERY_NONE,
                                                 0, 0, 0, qry, NULL, NULL);

To fetch documents with other keys other than "_id", same thing can be achieved easily too. Below is an example:

bson_t *qry = bson_new();
qry = BCON_NEW("$query", "{", "name", "{", "$in", "[",
               "Steve", "John", "Henry", "]", "}", "}");
mongoc_cursor_t *cursor = mongoc_collection_find(col, MONGOC_QUERY_NONE,
                                                 0, 0, 0, qry, NULL, NULL);

However, when I try to put the _id's in the array, I could not get it work. I tried two different ways. One is:

bson_oid_t oid1;
bson_oid_init_from_string(&oid1, "595320c208b0c52a8b37c151");
bson_oid_t oid2;
bson_oid_init_from_string(&oid2, "595320c208b0c52a8b37c152");
bson_oid_t oid3;
bson_oid_init_from_string(&oid3, "595320c208b0c52a8b37c153");
qry = BCON_NEW("$query", "{", "_id", "{", "$in", "[",
               oid1, oid2, oid3, "]", "}", "}");
mongoc_cursor_t *cursor = mongoc_collection_find(col, MONGOC_QUERY_NONE,
                                                 0, 0, 0, qry, NULL, NULL);

The other one is:

qry = BCON_NEW("$query", "{", "_id", "{", "$in", "[",
               "ObjectId(\"595320c208b0c52a8b37c151\")",
               "ObjectId(\"595320c208b0c52a8b37c152\")",
               "ObjectId(\"595320c208b0c52a8b37c153\")", "]", "}", "}");
mongoc_cursor_t *cursor = mongoc_collection_find(col, MONGOC_QUERY_NONE,
                                                 0, 0, 0, qry, NULL, NULL);

None of them returns any document.

Again, thank you very much for any suggestion, comment, in advance!


Edit:

I got my original question answered myself (see the answer below). However, if I want to dynamically form the query, in other words, the use case is that I get the list of ids from somewhere else, before forming the query, I don't know what the ids are, I only know they will be passed to me in a container, say std::vector<std::string>, how can I form this query dynamically?


Update:

Finally, I got the complete solution to my problem.

bson_init_from_json(qry,
                    "{\"_id\":{\"$in\":
                     [{\"$oid\":\"595320c208b0c52a8b37c151\"}, 
                      {\"$oid\":\"595320c208b0c52a8b37c152\"}, 
                      {\"$oid\":\"595320c208b0c52a8b37c153\"}]}}",
                    -1,
                    NULL);

As the above query is formed from a string, it can be updated dynamically, and thus completely solves my problem!


Solution

  • After some further investigation, I got my question answered myself. Instead of using oid variables directly or using strings, I should use the function BCON_OID. The following query helps fetch what I wanted:

    qry = BCON_NEW("$query", "{", "name", "{", "$in", "[",
                   BCON_OID(oid1), BCON_OID(oid2), BCON_OID(oid3), "]", "}", "}");