Join us Sept 17 at .local NYC! Use code WEB50 to save 50% on tickets. Learn more >
MongoDB Event
Docs 菜单
Docs 主页
/ / /
C 驱动程序
/ /

聚合框架示例

本文档提供了许多实际示例,展示了聚合框架的功能。

使用邮政编码数据集的 聚合示例使用了包含美国所有邮政编码和人口的公开数据集。此数据位于:zips.json。

让我们检查一下是否所有内容都已安装。

使用以下命令将 zips.json数据集加载到mongod实例:

$ mongoimport --drop -d test -c zipcodes zips.json

让我们使用MongoDB shell验证所有内容是否已成功导入。

$ mongo test
connecting to: test
> db.zipcodes.count()
29467
> db.zipcodes.findOne()
{
"_id" : "35004",
"city" : "ACMAR",
"loc" : [
-86.51557,
33.584132
],
"pop" : 6055,
"state" : "AL"
}

此集合中的每个文档均采用以下形式:

{
"_id" : "35004",
"city" : "Acmar",
"state" : "AL",
"pop" : 6055,
"loc" : [-86.51557, 33.584132]
}

在这些文档中:

  • _id 字段会将邮政编码以string形式保存。

  • city字段包含城市名称。

  • state 字段会包含两个字母的州缩写名。

  • pop 字段会保存人口数。

  • loc字段会以[latitude, longitude]数组的形式保存位置。

要获取人口超过10百万的所有州,请使用以下聚合管道:

聚合1 .c
#include <mongoc/mongoc.h>
#include <stdio.h>
static void
print_pipeline (mongoc_collection_t *collection)
{
mongoc_cursor_t *cursor;
bson_error_t error;
const bson_t *doc;
bson_t *pipeline;
char *str;
pipeline = BCON_NEW ("pipeline",
"[",
"{",
"$group",
"{",
"_id",
"$state",
"total_pop",
"{",
"$sum",
"$pop",
"}",
"}",
"}",
"{",
"$match",
"{",
"total_pop",
"{",
"$gte",
BCON_INT32 (10000000),
"}",
"}",
"}",
"]");
cursor = mongoc_collection_aggregate (collection, MONGOC_QUERY_NONE, pipeline, NULL, NULL);
while (mongoc_cursor_next (cursor, &doc)) {
str = bson_as_canonical_extended_json (doc, NULL);
printf ("%s\n", str);
bson_free (str);
}
if (mongoc_cursor_error (cursor, &error)) {
fprintf (stderr, "Cursor Failure: %s\n", error.message);
}
mongoc_cursor_destroy (cursor);
bson_destroy (pipeline);
}
int
main (void)
{
mongoc_client_t *client;
mongoc_collection_t *collection;
const char *uri_string = "mongodb://localhost:27017/?appname=aggregation-example";
mongoc_uri_t *uri;
bson_error_t error;
mongoc_init ();
uri = mongoc_uri_new_with_error (uri_string, &error);
if (!uri) {
fprintf (stderr,
"failed to parse URI: %s\n"
"error message: %s\n",
uri_string,
error.message);
return EXIT_FAILURE;
}
client = mongoc_client_new_from_uri (uri);
if (!client) {
return EXIT_FAILURE;
}
mongoc_client_set_error_api (client, 2);
collection = mongoc_client_get_collection (client, "test", "zipcodes");
print_pipeline (collection);
mongoc_uri_destroy (uri);
mongoc_collection_destroy (collection);
mongoc_client_destroy (client);
mongoc_cleanup ();
return EXIT_SUCCESS;
}

您应该会看到如下结果:

{ "_id" : "PA", "total_pop" : 11881643 }
{ "_id" : "OH", "total_pop" : 10847115 }
{ "_id" : "NY", "total_pop" : 17990455 }
{ "_id" : "FL", "total_pop" : 12937284 }
{ "_id" : "TX", "total_pop" : 16986510 }
{ "_id" : "IL", "total_pop" : 11430472 }
{ "_id" : "CA", "total_pop" : 29760021 }

上述聚合管道由两个管道操作符构建: $group$match

$group管道操作符需要_id字段,我们在其中指定分组;剩余字段指定如何生成复合值,并且必须使用群组聚合函数之一: $addToSet$first$last$max$min$avg$push$sum$match管道操作符语法与读取操作查询语法相同。

$group进程会读取所有文档,并为每个状态创建一个单独的文档,示例:

{ "_id" : "WA", "total_pop" : 4866692 }

total_pop字段使用 $sum聚合函数对源文档中所有 Pop 字段的值求和。

$group创建的文档通过管道传送到$match管道操作符。 它返回total_pop字段的值大于或等于10万的文档。

要获取每个城市平均人口最多的前三个州,请使用以下聚合:

pipeline = BCON_NEW ("pipeline", "[",
"{", "$group", "{", "_id", "{", "state", "$state", "city", "$city", "}", "pop", "{", "$sum", "$pop", "}", "}", "}",
"{", "$group", "{", "_id", "$_id.state", "avg_city_pop", "{", "$avg", "$pop", "}", "}", "}",
"{", "$sort", "{", "avg_city_pop", BCON_INT32 (-1), "}", "}",
"{", "$limit", BCON_INT32 (3) "}",
"]");

此聚合管道会生成:

{ "_id" : "DC", "avg_city_pop" : 303450.0 }
{ "_id" : "FL", "avg_city_pop" : 27942.29805615551 }
{ "_id" : "CA", "avg_city_pop" : 27735.341099720412 }

上述聚合管道由三个管道操作符构建: $group$sort$limit

第一个$group操作符创建以下文档:

{ "_id" : { "state" : "WY", "city" : "Smoot" }, "pop" : 414 }

请注意, $group操作符不能使用除_id字段之外的嵌套文档。

第二个$group使用这些文档创建以下文档:

{ "_id" : "FL", "avg_city_pop" : 27942.29805615551 }

这些文档按avg_city_pop字段降序排序。 最后, $limit管道操作符返回排序设立的前3文档。

后退

批量写入

在此页面上