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