0

I have documents in a mongo collection which look like: { "f" : [ 283, 180, 284 ], "l":["1","29"] } I am using the mongoDB c driver to fetch these documents and perform some operations on these> I would like to restore element "f" back as an array of integers and the element "l" back as an two multidimensional char array.

while (mongoc_cursor_next (cursor, &doc))
{
    bson_iter_t it;
    bson_iter_init(&it, doc);

    while (bson_iter_next(&it))
    {  
        const char * key=bson_iter_key(&it);
        bson_type_t type=bson_iter_type(&it);
        const uint8_t *data = NULL;
        uint32_t len = 0;
        bson_iter_array (&it, &len, &data);

    }

}

I am not able to figure out how I can extract "f" to int* and "l" to char**. I tried to type cast the pointer (data) to different types but the values are not proper. How do I go about it?

1 Answer 1

1

There are two ways. 1st, you can convert it to bson, and extract values by keys '1', '2', etc :

bson_t * doc = /*your bson doc*/;
bson_iter_t iter;
bson_iter_init(&iter, doc);

// requesting for f
bson_iter_find(&iter, "f");

const ui8 * data = NULL;
uint32_t len = 0;
bson_iter_array(&iter, &len, &data);

bson_t * fSubArray = bson_new_from_data(data, len);

bson_iter_t fIter;

bson_iter_init(&fIter, fSubArray);

bson_iter_find(&fIter, "0");
bson_iter_int32(&fIter) == 283;

bson_iter_find(&fIter, "1");
bson_iter_int32(&fIter) == 180;

bson_iter_find(&fIter, "2");
bson_iter_int32(&fIter) == 284;

// requesting for l
bson_iter_find(&iter, "l");

const ui8 * data = NULL;
uint32_t len = 0;
bson_iter_array(&iter, &len, &data);

bson_t * fSubArray = bson_new_from_data(data, len);

bson_iter_t fIter;

bson_iter_init(&fIter, fSubArray);

bson_iter_find(&fIter, "0");
strcmp(bson_iter_utf8(&fIter), "1") == 0;

bson_iter_find(&fIter, "1");
strcmp(bson_iter_utf8(&fIter), "29") == 0;

Also, mongoc recommend to use bson_uint32_to_string function for fast string to int converting.

2nd you can acces directly to data from bson_iter_array(&iter, &len, &data), if perfomance of first method isn't clear:

data has next format:

total bytes in data | bson type | string index           | 4 for int32, 1 for char, etc.| bson type | ... | end of data
4 bytes             |   1 byte  | null-terminated string | sizeof(element) bytes        | 1 byte    | ... | \0

so, if you know size of your data , you can access directly to it. But you should consider, that data has net byte order.

for example, if we know, that array is [int32(2), int64(4)], data would be:

4 bytes             | 1 byte          | null-terminated string | sizeof(int32) bytes      | 1 byte          | 1 byte  | sizeof(int64) bytes | \0
23 0 0 0            | 16              | 48 0                   | 2 0 0 0                  | 18              | 49 0    | 4 0 0 0 0 0 0 0     | 0
totaly 23 bytes     | BSON_TYPE_INT32 | "0\0"                  | 2                        | BSON_TYPE_INT64 | "1\0"   | 4                   | end
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.