问题
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:
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
来源:https://stackoverflow.com/questions/38237359/using-mongodb-c-driver-to-extract-array-from-bson