Loading

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;
}

运行结果:

参考来源

mongo-c-driver MongoDB使用笔记

SQL To MongoDB Mapping Chart

posted @ 2023-02-01 15:57  eiSouthBoy  阅读(368)  评论(0)    收藏  举报