libmongo-client 0.1.8
 
Loading...
Searching...
No Matches
Querying documents, part two

We learned how to make simple queries in the previous section, we'll be brave and do something much more advanced this time: we'll limit the query to documents that have their "yes?" field set to FALSE, and sort the results by the "n" field, in ascending order.

void
tut_sync_query_complex (void)
{
mongo_sync_connection *conn;
mongo_packet *p;
mongo_sync_cursor *cursor;
bson *query, *select;
gint i = 0;
conn = mongo_sync_connect ("localhost", 27017, FALSE);
if (!conn)
{
perror ("mongo_sync_connect()");
exit (1);
}
mongo_sync_connection * mongo_sync_connect(const gchar *address, gint port, gboolean slaveok)
Synchronously connect to a MongoDB server.
Definition mongo-sync.c:201

After our routine connect, we build the query and select BSON objects:

query = bson_build_full (BSON_TYPE_DOCUMENT, "$query", TRUE,
bson_build (BSON_TYPE_BOOLEAN, "yes?", FALSE,
BSON_TYPE_DOCUMENT, "$orderby", TRUE,
bson_finish (query);
select = bson_build (BSON_TYPE_INT32, "hello", 1,
BSON_TYPE_INT32, "n", 1,
BSON_TYPE_INT32, "yes?", 1,
bson_finish (select);
gboolean bson_finish(bson *b)
Finish a BSON object.
Definition bson.c:521
bson * bson_build(bson_type type, const gchar *name,...)
Build a BSON object in one go.
Definition bson.c:448
bson * bson_build_full(bson_type type, const gchar *name, gboolean free_after,...)
Build a BSON object in one go, with full control.
Definition bson.c:484
@ BSON_TYPE_DOCUMENT
4byte length + NULL terminated document
Definition bson.h:68
@ BSON_TYPE_NONE
Only used for errors.
Definition bson.h:65
@ BSON_TYPE_INT32
4byte integer
Definition bson.h:84
@ BSON_TYPE_BOOLEAN
1byte boolean value
Definition bson.h:73

Then we launch the query:

p = mongo_sync_cmd_query (conn, "tutorial.docs", 0,
0, 10, query, select);
if (!p)
{
perror ("mongo_sync_cmd_query()");
exit (1);
}
bson_free (query);
bson_free (select);
void bson_free(bson *b)
Free the memory associated with a BSON object.
Definition bson.c:579
mongo_packet * mongo_sync_cmd_query(mongo_sync_connection *conn, const gchar *ns, gint32 flags, gint32 skip, gint32 ret, const bson *query, const bson *sel)
Send a query command to MongoDB.
Definition mongo-sync.c:986

And make a cursor, just like last time:

cursor = mongo_sync_cursor_new (conn, "tutorial.docs", p);
if (!cursor)
{
perror ("mongo_sync_cursor_new()");
exit (1);
}
mongo_sync_cursor * mongo_sync_cursor_new(mongo_sync_connection *conn, const gchar *ns, mongo_packet *packet)
Create a new MongoDB Cursor.
Definition mongo-sync-cursor.c:28

And that's pretty much the bulk of what we wanted to do: we just constructed our query and select BSON objects appropriately, and mongo_sync_cmd_query() does the rest.

But just to make sure our results are sane, we iterate over the returned documents, and print the fields we're interested in:

while (mongo_sync_cursor_next (cursor))
{
const char *hello;
gint32 n;
gboolean yes;
bson *result;
bson_cursor *c;
result = mongo_sync_cursor_get_data (cursor);
if (!result)
{
perror ("mongo_sync_cursor_get_data()");
exit (1);
}
c = bson_find (result, "hello");
if (!bson_cursor_get_string (c, &hello))
{
perror ("bson_cursor_get_string()");
exit (1);
}
c = bson_find (result, "n");
if (!bson_cursor_get_int32 (c, &n))
{
perror ("bson_cursor_get_int32()");
exit (1);
}
c = bson_find (result, "yes?");
if (!bson_cursor_get_boolean (c, &yes))
{
perror ("bson_cursor_get_boolean()");
exit (1);
}
printf ("Document #%d: hello=%s; n=%d; yes?=%s\n",
i, hello, n, (yes) ? "TRUE" : "FALSE");
bson_free (result);
i++;
gboolean bson_cursor_get_boolean(const bson_cursor *c, gboolean *dest)
Get the value stored at the cursor, as a boolean.
Definition bson.c:1113
gboolean bson_cursor_get_string(const bson_cursor *c, const gchar **dest)
Get the value stored at the cursor, as string.
Definition bson.c:1007
gboolean bson_cursor_get_int32(const bson_cursor *c, gint32 *dest)
Get the value stored at the cursor, as a 32-bit integer.
Definition bson.c:1212
void bson_cursor_free(bson_cursor *c)
Delete a cursor, and free up all resources used by it.
Definition bson.c:800
bson_cursor * bson_find(const bson *b, const gchar *name)
Create a new cursor positioned at a given key.
Definition bson.c:955
gboolean mongo_sync_cursor_next(mongo_sync_cursor *cursor)
Iterate a MongoDB cursor.
Definition mongo-sync-cursor.c:56
bson * mongo_sync_cursor_get_data(mongo_sync_cursor *cursor)
Retrieve the BSON document at the cursor's position.
Definition mongo-sync-cursor.c:99
}

And when that is done, all that is left, is to clean up after ourselves:

}
void mongo_sync_cursor_free(mongo_sync_cursor *cursor)
Free a MongoDB cursor.
Definition mongo-sync-cursor.c:83
void mongo_sync_disconnect(mongo_sync_connection *conn)
Close and free a synchronous MongoDB connection.
Definition mongo-sync.c:396