有关特定的平台上安装MongoDB C驱动程序的详细说明,请参官方文档:http://mongoc.org/.
MongoDB C 驱动程序的安装、编译:http://www.cnblogs.com/oloroso/p/5740431.html
$ mongo --host localhost --port 27017
MongoDB shell version: 3.0.6
connecting to: localhost:27017/test
MongoDB C Driver程序通过mongoc_client_t提供了一种简便的访问MongoDB的方法( 与集群配置无关的)。
它满足透明地连接到独立的服务器,副本集和分片集群上的需求。一旦建立了连接,数据库和集合的句柄可以通过结构mongoc_database_t和mongoc_collection_t分别得到。然后可以通过这些句柄执行MongoDB操作。
在应用程序的启动后,先调用mongoc_init(),libmongoc 的任何其他功能才能正确使用,并需要在退出之前调用mongoc_cleanup()。当创建client、database和server的句柄后,需要在使用完后调用适当的销毁函数。
下面的示例建立一个独立的服务器上的本地主机的连接,并执行一个简单的命令。有关数据库操作的详细信息可以查看CRUD 操作和执行命令部分。连接到副本集和分片集群的例子可以在高级连接页面查看。
connect.c
#include <bson.h>
#include <bcon.h>
#include <mongoc.h>
int
main (int argc,
char *argv[])
{
mongoc_client_t *client;
mongoc_database_t *database;
mongoc_collection_t *collection;
bson_t *command,
reply,
*insert;
bson_error_t error;
char *str;
bool retval;
/*
* 初始化libmongoc's
*/
mongoc_init ();
/*
* 创建一个新的client实例
*/
client = mongoc_client_new ("mongodb://localhost:27017");
/*
* 获取数据库"db_name"和集合"coll_name"的句柄
*/
database = mongoc_client_get_database (client, "db_name");
collection = mongoc_client_get_collection (client, "db_name", "coll_name");
/*
* 执行操作。此处以执行ping数据库,以json格式打印结果。并执行一个插入操作。
*/
// 执行命令操作(ping)
command = BCON_NEW ("ping", BCON_INT32 (1));
retval = mongoc_client_command_simple (client, "admin", command, NULL, &reply, &error);
if (!retval) {
fprintf (stderr, "%s\n", error.message);
return EXIT_FAILURE;
}
// 获取json形式的结果
str = bson_as_json (&reply, NULL);
printf ("%s\n", str); // 打印输出
// 插入操作命令
insert = BCON_NEW ("hello", BCON_UTF8 ("world"));
if (!mongoc_collection_insert (collection, MONGOC_INSERT_NONE, insert, NULL, &error)) {
fprintf (stderr, "%s\n", error.message);
}
// 释放资源
bson_destroy (insert);
bson_destroy (&reply);
bson_destroy (command);
bson_free (str);
/*
* 释放拥有的句柄并清理libmongoc
*/
mongoc_collection_destroy (collection);
mongoc_database_destroy (database);
mongoc_client_destroy (client);
mongoc_cleanup ();
return 0;
}
$ gcc -o connect connect.c $(pkg-config --cflags --libs libmongoc-1.0)
$ ./connect
{ "ok" : 1.000000 }
$ gcc -o connect connect.c -I/usr/local/include -lmongoc-1.0 -lbson-1.0
$ ./connect
{ "ok" : 1.000000 }
C:\> cl.exe /IC:\mongo-c-driver\include\libbson-1.0 /IC:\mongo-c-driver\include\libmongoc-1.0 connect.c
C:\> connect
{ "ok" : 1.000000 }
#include <bson.h>
int
main (int argc,
char *argv[])
{
bson_t *document;
bson_t child;
char *str;
document = bson_new ();
/*
* 追加{"hello" : "world"}到document.
* 传递 -1 作为长度参数,告诉libbson自己去计算字符串长度.
*/
bson_append_utf8 (document, "hello", -1, "world", -1);
/*
* 方便使用的, 这个宏与上面是等效的。
*/
BSON_APPEND_UTF8 (document, "hello", "world");
/*
* 开始一个子文档
*/
BSON_APPEND_DOCUMENT_BEGIN (document, "subdoc", &child);
BSON_APPEND_UTF8 (&child, "subkey", "value");
bson_append_document_end (document, &child);
/*
* 打印这个BSON对象,以json字符串格式。
*/
str = bson_as_json (document, NULL);
printf ("%s\n", str);
bson_free (str);
/*
* 清理已分配的bson documents.
*/
bson_destroy (document);
return 0;
}
#include <bcon.h>
#include <bson.h>
#include <stdio.h>
int
main (int argc,
char *argv[])
{
bson_t *doc;
char *str;
doc = BCON_NEW ("name", BCON_UTF8 ("Babe Ruth"),
"statistics", "{",
"batting_average", BCON_DOUBLE (.342),
"hits", BCON_INT32 (2873),
"home_runs", BCON_INT32 (714),
"rbi", BCON_INT32 (2213),
"}",
"nicknames", "[",
BCON_UTF8 ("the Sultan of Swat"),
BCON_UTF8 ("the Bambino"),
"]");
str = bson_as_json (doc, NULL);
printf ("%s\n", str);
bson_free (str);
bson_destroy (doc);
return 0;
}
#include <bson.h>
int
main (int argc,
char *argv[])
{
bson_error_t error;
bson_t *bson;
char *string;
const char *json = "{\"hello\": \"world\"}";
bson = bson_new_from_json ((const uint8_t *)json, -1, &error);
if (!bson) {
fprintf (stderr, "%s\n", error.message);
return EXIT_FAILURE;
}
string = bson_as_json (bson, NULL);
printf ("%s\n", string);
bson_free (string);
return 0;
}
若要向集合中插入文件,首先通过mongoc_client_t获取mongoc_collection_t的句柄。然后使用mongoc_collection_insert()将BSON文档添加到集合。
本示例将插入记录到数据库"mydb"和集合"mycoll"。
当完成后,确保分配的结构使用他们各自的销毁函数进行释放。
insert.c
#include <bson.h>
#include <mongoc.h>
#include <stdio.h>
int
main (int argc,
char *argv[])
{
mongoc_client_t *client;
mongoc_collection_t *collection;
bson_error_t error;
bson_oid_t oid;
bson_t *doc;
// 初始化libmongoc
mongoc_init ();
// 连接到数据库,并获取集合句柄
client = mongoc_client_new ("mongodb://localhost:27017/");
collection = mongoc_client_get_collection (client, "mydb", "mycoll");
// 创建一个bson文档,并追加键值对数据
doc = bson_new ();
bson_oid_init (&oid, NULL);
BSON_APPEND_OID (doc, "_id", &oid);
BSON_APPEND_UTF8 (doc, "hello", "world");
// 将bson文档插入到集合
if (!mongoc_collection_insert (collection, MONGOC_INSERT_NONE, doc, NULL, &error)) {
fprintf (stderr, "%s\n", error.message);
}
// 释放资源
bson_destroy (doc);
mongoc_collection_destroy (collection);
mongoc_client_destroy (client);
// 清理libmongoc
mongoc_cleanup ();
return 0;
}
$ gcc -o insert insert.c $(pkg-config --cflags --libs libmongoc-1.0)
$ ./insert
C:\> cl.exe /IC:\mongo-c-driver\include\libbson-1.0 /IC:\mongo-c-driver\include\libmongoc-1.0 insert.c
C:\> insert
$ mongo
MongoDB shell version: 3.0.6
connecting to: test
> use mydb
switched to db mydb
> db.mycoll.find()
{ "_id" : ObjectId("55ef43766cb5f36a3bae6ee4"), "hello" : "world" }
>
>
若使用C Dirver程序去查询MongoDB 集合,请使用函数mongoc_collection_find()。将返回一个匹配的文档的cursor(游标)。
下面示例循环访问result cursor(结果游标)并打印到为JSON字符串到标准输出。
请注意,mongoc_collection_find使用BSON文档作为查询说明符;
例如,{ “color” : “red” }将匹配所有文档中字段名为color且值为red的。空文档{}可以用于匹配的所有文件。
这第一个示例使用空查询说明符,来找到所有"mydb"数据库中"mycoll"集合的文档。
find.c
#include <bson.h>
#include <mongoc.h>
#include <stdio.h>
int
main (int argc,
char *argv[])
{
mongoc_client_t *client;
mongoc_collection_t *collection;
mongoc_cursor_t *cursor;
const bson_t *doc;
bson_t *query;
char *str;
mongoc_init ();
client = mongoc_client_new ("mongodb://localhost:27017/");
collection = mongoc_client_get_collection (client, "mydb", "mycoll");
// query是一个空的BSON文档,用于做查询说明符的时候匹配所有文档。
query = bson_new ();
// 执行查询操作
cursor = mongoc_collection_find (collection, MONGOC_QUERY_NONE, 0, 0, 0, query, NULL, NULL);
while (mongoc_cursor_next (cursor, &doc)) {
str = bson_as_json (doc, NULL);
printf ("%s\n", str);
bson_free (str);
}
bson_destroy (query);
mongoc_cursor_destroy (cursor);
mongoc_collection_destroy (collection);
mongoc_client_destroy (client);
mongoc_cleanup ();
return 0;
}
$ gcc -o find find.c $(pkg-config --cflags --libs libmongoc-1.0)
$ ./find
{ "_id" : { "$oid" : "55ef43766cb5f36a3bae6ee4" }, "hello" : "world" }
C:\> cl.exe /IC:\mongo-c-driver\include\libbson-1.0 /IC:\mongo-c-driver\include\libmongoc-1.0 find.c
C:\> find
{ "_id" : { "$oid" : "55ef43766cb5f36a3bae6ee4" }, "hello" : "world" }
若要查找特定的文档,将添加指定的查询说明符。本示例将添加对BSON_APPEND_UTF8()的调用来寻找匹配{“hello”:“world”}的所有文档。
find-specific.c
#include <bson.h>
#include <mongoc.h>
#include <stdio.h>
int
main (int argc,
char *argv[])
{
mongoc_client_t *client;
mongoc_collection_t *collection;
mongoc_cursor_t *cursor;
const bson_t *doc;
bson_t *query;
char *str;
mongoc_init ();
client = mongoc_client_new ("mongodb://localhost:27017/");
collection = mongoc_client_get_collection (client, "mydb", "mycoll");
// query在这里将添加一个键值对,查询的时候将只查询出匹配上的结果
query = bson_new ();
BSON_APPEND_UTF8 (query, "hello", "world");
cursor = mongoc_collection_find (collection, MONGOC_QUERY_NONE, 0, 0, 0, query, NULL, NULL);
while (mongoc_cursor_next (cursor, &doc)) {
str = bson_as_json (doc, NULL);
printf ("%s\n", str);
bson_free (str);
}
bson_destroy (query);
mongoc_cursor_destroy (cursor);
mongoc_collection_destroy (collection);
mongoc_client_destroy (client);
mongoc_cleanup ();
return 0;
}
编译运行
$ gcc -o find-specific find-specific.c $(pkg-config --cflags --libs libmongoc-1.0)
$ ./find-specific
{ "_id" : { "$oid" : "55ef43766cb5f36a3bae6ee4" }, "hello" : "world" }
C:\> cl.exe /IC:\mongo-c-driver\include\libbson-1.0 /IC:\mongo-c-driver\include\libmongoc-1.0 find-specific.c
C:\> find-specific
{ "_id" : { "$oid" : "55ef43766cb5f36a3bae6ee4" }, "hello" : "world" }
下面的示例使用"mydb"数据库,将文档插入到"mycoll"集合。然后利用其_id字段,更新文档的值(key对应的value),并添加一个新的字段(updated)。
update.c
#include <bcon.h>
#include <bson.h>
#include <mongoc.h>
#include <stdio.h>
int
main (int argc,
char *argv[])
{
mongoc_collection_t *collection;
mongoc_client_t *client;
bson_error_t error;
bson_oid_t oid;
bson_t *doc = NULL;
bson_t *update = NULL;
bson_t *query = NULL;
mongoc_init ();
client = mongoc_client_new ("mongodb://localhost:27017/");
collection = mongoc_client_get_collection (client, "mydb", "mycoll");
// 初始化一个对象ID
bson_oid_init (&oid, NULL);
doc = BCON_NEW ("_id", BCON_OID (&oid)/*使用上面初始化的oid*/,
"key", BCON_UTF8 ("old_value"));
// 插入到数据库中
if (!mongoc_collection_insert (collection, MONGOC_INSERT_NONE, doc, NULL, &error)) {
fprintf (stderr, "%s\n", error.message);
goto fail;
}
// 注意,这里使用的oid是之前插入一样的
query = BCON_NEW ("_id", BCON_OID (&oid));
update = BCON_NEW ("$set", "{",
"key", BCON_UTF8 ("new_value")/*修改值*/,
"updated", BCON_BOOL (true) /*添加的字段*/,
"}");
// 执行update操作。这个操作将使用update的内容去替换之前插入到数据库中的doc的内容
if (!mongoc_collection_update (collection, MONGOC_UPDATE_NONE, query, update, NULL, &error)) {
fprintf (stderr, "%s\n", error.message);
goto fail;
}
fail:
if (doc)
bson_destroy (doc);
if (query)
bson_destroy (query);
if (update)
bson_destroy (update);
mongoc_collection_destroy (collection);
mongoc_client_destroy (client);
mongoc_cleanup ();
return 0;
}
$ gcc -o update update.c $(pkg-config --cflags --libs libmongoc-1.0)
$ ./update
C:\> cl.exe /IC:\mongo-c-driver\include\libbson-1.0 /IC:\mongo-c-driver\include\libmongoc-1.0 update.c
C:\> update
{ "_id" : { "$oid" : "55ef43766cb5f36a3bae6ee4" }, "hello" : "world" }
$ mongo
MongoDB shell version: 3.0.6
connecting to: test
> use mydb
switched to db mydb
> db.mycoll.find({"updated" : true})
{ "_id" : ObjectId("55ef549236fe322f9490e17b"), "updated" : true, "key" : "new_value" }
>
本示例说明了使用mongoc_collection_delete_one()来删除文档。
下面的代码插入一个示例文档到数据库"mydb"的"mycoll"集合。然后,它会删除所有与{“hello”:“world”}相匹配的文档。
delete.c
#include <bson.h>
#include <mongoc.h>
#include <stdio.h>
int
main (int argc,
char *argv[])
{
mongoc_client_t *client;
mongoc_collection_t *collection;
bson_error_t error;
bson_oid_t oid;
bson_t *doc;
mongoc_init ();
client = mongoc_client_new ("mongodb://localhost:27017/");
collection = mongoc_client_get_collection (client, "test", "test");
doc = bson_new ();
bson_oid_init (&oid, NULL);
BSON_APPEND_OID (doc, "_id", &oid);
BSON_APPEND_UTF8 (doc, "hello", "world"); // 添加hello字段,值为world
// 插入文档
if (!mongoc_collection_insert (collection, MONGOC_INSERT_NONE, doc, NULL, &error)) {
fprintf (stderr, "Insert failed: %s\n", error.message);
}
bson_destroy (doc);
doc = bson_new ();
BSON_APPEND_OID (doc, "_id", &oid); // 这里只添加了_id字段
// 这里与上面描述的有点不一致,因为这里匹配的只是上面插入的,而不是含hello字段,且值为world的
// 如果按照描述的话,这里应该改为BSON_APPEND_UTF8(doc,"hello","world")才行。
// 执行删除操作。这里只能匹配_id字段,也就只能删除上面插入的文档
if (!mongoc_collection_remove (collection, MONGOC_REMOVE_SINGLE_REMOVE, doc, NULL, &error)) {
fprintf (stderr, "Delete failed: %s\n", error.message);
}
bson_destroy (doc);
mongoc_collection_destroy (collection);
mongoc_client_destroy (client);
mongoc_cleanup ();
return 0;
}
$ gcc -o delete delete.c $(pkg-config --cflags --libs libmongoc-1.0)
$ ./delete
C:\> cl.exe /IC:\mongo-c-driver\include\libbson-1.0 /IC:\mongo-c-driver\include\libmongoc-1.0 delete.c
C:\> delete
使用MongoDB Shell证明文件已成功删除。
$ mongo
MongoDB shell version: 3.0.6
connecting to: test
> use mydb
switched to db mydb
> db.mycoll.count({"hello" : "world"})
0
这里的标题应该改为文档计数会更合理。
计数MongoDB 集合中的文档数目类似于执行查找操作。此示例在数据库"mydb"中"mycoll"集合中获取与{“hello”:“world”}相匹配的文档的数目。
count.c
#include <bson.h>
#include <mongoc.h>
#include <stdio.h>
int
main (int argc,
char *argv[])
{
mongoc_client_t *client;
mongoc_collection_t *collection;
bson_error_t error;
bson_t *doc;
int64_t count;
mongoc_init ();
client = mongoc_client_new ("mongodb://localhost:27017/");
collection = mongoc_client_get_collection (client, "mydb", "mycoll");
// doc用于计数时候做匹配
doc = bson_new_from_json ((const uint8_t *)"{\"hello\" : \"world\"}", -1, &error);
// 进行统计操作
count = mongoc_collection_count (collection, MONGOC_QUERY_NONE, doc, 0, 0, NULL, &error);
if (count < 0) {
fprintf (stderr, "%s\n", error.message);
} else {
printf ("%" PRId64 "\n", count);
}
bson_destroy (doc);
mongoc_collection_destroy (collection);
mongoc_client_destroy (client);
mongoc_cleanup ();
return 0;
}
对代码进行编译和运行它︰
Linux和Unix下:
$ gcc -o count count.c $(pkg-config --cflags --libs libmongoc-1.0)
$ ./count
1
C:\> cl.exe /IC:\mongo-c-driver\include\libbson-1.0 /IC:\mongo-c-driver\include\libmongoc-1.0 count.c
C:\> count
驱动程序提供在客户端执行MongoDB命令操作数据库和集合结构的helper functions(辅助函数)。这些函数返回的cursor游标。这些函数的*_simple变体形式返回指示成功或失败的布尔值。
本示例针对数据库"mydb"中的"mycoll"集合执行collStats(获取集合状态信息)命令。
executing.c
#include <bson.h>
#include <bcon.h>
#include <mongoc.h>
#include <stdio.h>
int
main (int argc,
char *argv[])
{
mongoc_client_t *client;
mongoc_collection_t *collection;
bson_error_t error;
bson_t *command;
bson_t reply;
char *str;
mongoc_init ();
client = mongoc_client_new ("mongodb://localhost:27017/");
collection = mongoc_client_get_collection (client, "mydb", "mycoll");
// 创建命令(命令也是一个BSON文档)
command = BCON_NEW ("collStats",BCON_UTF8 ("mycoll"));
// 执行命令。注意,这里使用的是_simple变体形式
if (mongoc_collection_command_simple (collection, command, NULL, &reply, &error)) {
str = bson_as_json (&reply, NULL);
printf ("%s\n", str);
bson_free (str);
} else {
fprintf (stderr, "Failed to run command: %s\n", error.message);
}
bson_destroy (command);
bson_destroy (&reply);
mongoc_collection_destroy (collection);
mongoc_client_destroy (client);
mongoc_cleanup ();
return 0;
}
$ gcc -o executing executing.c $(pkg-config --cflags --libs libmongoc-1.0)
$ ./executing
{ "ns" : "mydb.mycoll", "count" : 1, "size" : 48, "avgObjSize" : 48, "numExtents" : 1, "storageSize" : 8192,
"lastExtentSize" : 8192.000000, "paddingFactor" : 1.000000, "userFlags" : 1, "capped" : false, "nindexes" : 1,
"indexDetails" : { }, "totalIndexSize" : 8176, "indexSizes" : { "_id_" : 8176 }, "ok" : 1.000000 }
C:\> cl.exe /IC:\mongo-c-driver\include\libbson-1.0 /IC:\mongo-c-driver\include\libmongoc-1.0 executing.c
C:\> executing
{ "ns" : "mydb.mycoll", "count" : 1, "size" : 48, "avgObjSize" : 48, "numExtents" : 1, "storageSize" : 8192,
"lastExtentSize" : 8192.000000, "paddingFactor" : 1.000000, "userFlags" : 1, "capped" : false, "nindexes" : 1,
"indexDetails" : { }, "totalIndexSize" : 8176, "indexSizes" : { "_id_" : 8176 }, "ok" : 1.000000 }
MongoDB C Driver程序在绝大多数相关操作是线程未知的。这意味着它是由程序员来保证线程安全性。
然而,mongoc_client_pool_t(mongoc客户端池)是线程安全,用于以线程安全的方式获取mongoc_client_t。然后后从pool中检索client,client structure应调用线程持有。该线程完成后,client应该放回池中。
#include <mongoc.h>
#include <pthread.h>
#define N_THREADS 10
// 线程工作函数
static void *
worker (void *data) {
mongoc_client_pool_t *pool = data;
mongoc_client_t *client;
// 从客户端池中获取一个客户端
client = mongoc_client_pool_pop (pool);
/* Do something... */
// 用完后需要还回客户端池
mongoc_client_pool_push (pool, client);
return NULL;
}
int
main (int argc,
char *argv[])
{
mongoc_client_pool_t *pool;
mongoc_uri_t *uri;
pthread_t threads[N_THREADS];
mongoc_init ();
uri = mongoc_uri_new ("mongodb://localhost/");
// 创建客户端池
pool = mongoc_client_pool_new (uri);
// 循环创建线程
for (i = 0; i < N_THREADS; i++) {
pthread_create (&threads[i], NULL, worker, pool);
}
// 等待各个线程结束
for (i = 0; i < N_THREADS; i++) {
pthread_join (threads[i], NULL);
}
// 是否客户端池
mongoc_client_pool_destroy (pool);
mongoc_uri_destroy (uri);
mongoc_cleanup ();
return 0;
}