MongoDB的高级查询
一、前言
MongoDB的基础查询在之前发布随笔有记录,随笔链接libmongoc库和libbson库的使用
基础查询语句匹配SQL:SELECT * FROM 表名 WHERE id=1001
, 不带输出条件。
libmongoc库使用的接口函数:
mongoc_cursor_t *
mongoc_collection_find_with_opts (mongoc_collection_t *collection,
const bson_t *filter,
const bson_t *opts,
const mongoc_read_prefs_t *read_prefs)
mongoc_cursor_t *
mongoc_collection_aggregate (mongoc_collection_t *collection,
mongoc_query_flags_t flags,
const bson_t *pipeline,
const bson_t *opts,
const mongoc_read_prefs_t *read_prefs)
输出条件:
1)指定输出列
2)使用聚集函数
3)排序
4)分组
二、高级查询
2-1 指定输出列
输出条件:id、name、age
WHERE条件:{name:"LiSi", "age":18, "sex":"male"}
#include <mongoc/mongoc.h>
#include <bson/bson.h>
static int lib_collection_read_document(const char *uri_string, const char *database_name, const char *collection_name, const char *json_opts,
char doc_list_arr[][300], int *num_of_docs)
{
mongoc_client_t *client = NULL;
mongoc_collection_t *collection = NULL;
mongoc_cursor_t *cursor = NULL;
bson_error_t error;
const bson_t *doc = NULL;
bson_t *query = NULL, *opts = NULL;
char *str = NULL;
int result = 0;
client = mongoc_client_new(uri_string);
collection = mongoc_client_get_collection(client, database_name, collection_name);
query = bson_new_from_json((unsigned char *)json_opts, -1, &error);
if (!query)
{
fprintf(stderr, "%s\n", error.message);
result = -1;
}
// 带输出条件
char json[100] = { "{\"projection\":{\"id\":1,\"name\":1,\"age\":1}}" };
opts = bson_new_from_json((unsigned char *)json, -1, &error);
cursor = mongoc_collection_find_with_opts(collection, query, opts, NULL);
while (mongoc_cursor_next(cursor, &doc))
{
//str = bson_as_canonical_extended_json(doc, NULL);
//str = bson_as_relaxed_extended_json(doc, NULL);
str = bson_as_json(doc, NULL);
sprintf(doc_list_arr[*num_of_docs], "%s", str);
(*num_of_docs)++;
bson_free(str);
}
bson_destroy(opts);
bson_destroy(query);
mongoc_cursor_destroy(cursor);
mongoc_collection_destroy(collection);
mongoc_client_destroy(client);
return result;
}
int main(int argc, char *argv[])
{
mongoc_init();
const char *uri_string = "mongodb://10.8.198.55:27017";
const char *database = "event_database";
const char *collection = "student_coll";
/* read documents from collection with options */
char json_opts[300] = {"{\"name\":\"LiSi\",\"age\":18,\"sex\":\"male\"}"};
char doc_list_arr[100][300] = {0};
int num_of_docs = 0;
lib_collection_read_document(uri_string, database, collection, json_opts, doc_list_arr, &num_of_docs);
for (int i = 0; i < num_of_docs; i++)
{
printf("%s\n", doc_list_arr[i]);
}
mongoc_cleanup();
return 0;
}
程序运行结果:
注意:_id列虽然没有指定输出,但还是被打印出来了,_id是MongoDB自动添加的id字段。可以在输出条件增加 "_id":0
2-2 排序
输出条件:id、name、age 和 按照age升序排列
WHERE条件:{name:"LiSi"}
#include <mongoc/mongoc.h>
#include <bson/bson.h>
static int lib_collection_read_document(const char *uri_string, const char *database_name, const char *collection_name, const char *json_opts,
char doc_list_arr[][300], int *num_of_docs)
{
mongoc_client_t *client = NULL;
mongoc_collection_t *collection = NULL;
mongoc_cursor_t *cursor = NULL;
bson_error_t error;
const bson_t *doc = NULL;
bson_t *query = NULL, *opts = NULL;
char *str = NULL;
int result = 0;
client = mongoc_client_new(uri_string);
collection = mongoc_client_get_collection(client, database_name, collection_name);
query = bson_new_from_json((unsigned char *)json_opts, -1, &error);
if (!query)
{
fprintf(stderr, "%s\n", error.message);
result = -1;
}
// 带输出条件
char json[100] = { "{\"projection\":{\"_id\":0,\"id\":1,\"name\":1,\"age\":1},\"sort\":{\"age\":1}}" };
opts = bson_new_from_json((unsigned char *)json, -1, &error);
cursor = mongoc_collection_find_with_opts(collection, query, opts, NULL);
while (mongoc_cursor_next(cursor, &doc))
{
//str = bson_as_canonical_extended_json(doc, NULL);
//str = bson_as_relaxed_extended_json(doc, NULL);
str = bson_as_json(doc, NULL);
sprintf(doc_list_arr[*num_of_docs], "%s", str);
(*num_of_docs)++;
bson_free(str);
}
bson_destroy(opts);
bson_destroy(query);
mongoc_cursor_destroy(cursor);
mongoc_collection_destroy(collection);
mongoc_client_destroy(client);
return result;
}
int main(int argc, char *argv[])
{
mongoc_init();
const char *uri_string = "mongodb://10.8.198.55:27017";
const char *database = "event_database";
const char *collection = "student_coll";
/* read documents from collection with options */
char json_opts[300] = {"{\"name\":\"LiSi\"};
char doc_list_arr[100][300] = {0};
int num_of_docs = 0;
lib_collection_read_document(uri_string, database, collection, json_opts, doc_list_arr, &num_of_docs);
for (int i = 0; i < num_of_docs; i++)
{
printf("%s\n", doc_list_arr[i]);
}
mongoc_cleanup();
return 0;
}
运行结果:
2-3 统计结果集数量
统计符合条件的document数量
#include <mongoc/mongoc.h>
#include <bson/bson.h>
static int lib_collection_count_document(const char *uri_string, const char *database_name, const char *collection_name, const char *json_filter,
const char *json_opts)
{
mongoc_client_t *client = NULL;
mongoc_collection_t *collection = NULL;
bson_error_t error;
bson_t *filter = NULL, *opts = NULL;
int result = 0;
client = mongoc_client_new(uri_string);
collection = mongoc_client_get_collection(client, database_name, collection_name);
filter = bson_new_from_json((unsigned char *)json_filter, -1, &error);
opts = bson_new_from_json((unsigned char *)json_opts, -1, &error);
int count = (int)mongoc_collection_count_documents(collection, filter, opts, NULL, NULL, &error);
bson_destroy(opts);
bson_destroy(filter);
mongoc_collection_destroy(collection);
mongoc_client_destroy(client);
return count;
}
int main(int argc, char *argv[])
{
mongoc_init();
const char *uri_string = "mongodb://10.8.198.55:27017";
const char *database = "event_database";
const char *collection = "student_coll";
/* count documents with options in collection */
char json_filter[300] = { "{\"name\":\"LiSi\"}" };
char json_opts[100] = { "{\"skip\":1}" };
int count = lib_collection_count_document(uri_string, database, collection, json_filter, json_opts);
printf("符合条件的数量:%d\n", count);
mongoc_cleanup();
return 0;
}
运行结果:
2-4 聚合函数
若想搜索:{size:"medium"}
且 按照 name
进行过滤,name一样的只输出一次
数据来源:
代码实现:
#include <mongoc/mongoc.h>
#include <bson/bson.h>
static int lib_collection_aggregation_docement(const char *uri_string, const char *database_name, const char *collection_name, const char *json_pipeline,
const char *json_opts, char doc_list_arr[][300], int *num_of_docs)
{
mongoc_client_t *client = NULL;
mongoc_collection_t *collection = NULL;
mongoc_cursor_t *cursor = NULL;
bson_error_t error;
const bson_t *doc = NULL;
bson_t *pipeline = NULL, *opts = NULL;
char *str = NULL;
client = mongoc_client_new(uri_string);
collection = mongoc_client_get_collection(client, database_name, collection_name);
pipeline = bson_new_from_json((unsigned char *)json_pipeline, -1, &error);
//opts = bson_new_from_json((unsigned char *)json_opts, -1, &error);
cursor = mongoc_collection_aggregate(collection, MONGOC_QUERY_NONE, pipeline, NULL, NULL);
while (mongoc_cursor_next(cursor, &doc))
{
str = bson_as_json(doc, NULL);
sprintf(doc_list_arr[*num_of_docs], "%s", str);
(*num_of_docs)++;
bson_free(str);
}
bson_destroy(opts);
bson_destroy(pipeline);
mongoc_cursor_destroy(cursor);
mongoc_collection_destroy(collection);
mongoc_client_destroy(client);
return 0;
}
int main(int argc, char *argv[])
{
mongoc_init();
const char *uri_string = "mongodb://10.8.198.55:27017";
const char *database = "event_database";
const char *collection = "orders";
/* aggregation */
char json_pipeline[300] = {"{\"pipeline\":[{\"$match\":{\"size\":\"medium\"}},{\"$group\":{\"_id\":\"$name\"}}]}"};
char json_opts[300] = {0};
char doc_list_arr[100][300] = {0};
int num_of_docs = 0;
printf("json_pipeline:%s\n", json_pipeline);
lib_collection_aggregation_docement(uri_string, database, collection, json_pipeline, json_opts, doc_list_arr, &num_of_docs);
for (int i = 0; i < num_of_docs; i++)
{
printf("%s\n", doc_list_arr[i]);
}
mongoc_cleanup();
return 0;
}
运行结果: