这是我收藏的结构部分:
{
...
list: [
{ id:'00A', name:'None 1' },
{ id:'00B', name:'None 2' },
],
...
}
在使用了函数“distinct”之后(参见链接:mongodb-C 中的子数组中的子对象)
请问我计算子文件数量的最佳解决方案是什么?
因为 mongo_count 的使用与 distinct 和 mongo_run_command() 函数不兼容。
这是我收藏的结构部分:
{
...
list: [
{ id:'00A', name:'None 1' },
{ id:'00B', name:'None 2' },
],
...
}
在使用了函数“distinct”之后(参见链接:mongodb-C 中的子数组中的子对象)
请问我计算子文件数量的最佳解决方案是什么?
因为 mongo_count 的使用与 distinct 和 mongo_run_command() 函数不兼容。
如果您在问题中包含更多信息(例如您使用的版本以及您的总体目标是什么),将会很有帮助。Mongo 是非常特定于用例的。我了解您正在寻找数组中不同元素的计数。当涉及到数组时,聚合框架 [AF] 通常是完成任务的最简单方法(遗憾的是,此时您可能还需要使用 map reduce 来处理更复杂的查询)。您应该针对您的具体情况修改下面的示例。此示例适用于 C 驱动程序 0.8 和 mongodb 2.4.6。除了使用 distinct 之外,Mongo 与 SQL 有一个很大的不同。子文档以二进制表示进行比较(示例如下)。因此,Mongo 中 distinct 的含义与子文档的 SQL 术语略有不同。所以 {... , subdoc:[{a:1,b:1}]} {..., subdoc:[{b:1,a:1}]} 表示 subdoc 的两个不同值。这仅适用于子文档;顶级字段可以按任何顺序排列。此外,Mongo 不保证文档中的字段顺序,数组除外。因此,虽然 subdoc.a 上的聚合将保证您获得的结果(假设 a 本身也不是子文档),但 subdoc 上的聚合不会。
如果要按字段映射减少子文档字段,可以使用。复杂度图减少比 AF 高几个数量级。如果您想了解 MapReduce:http ://docs.mongodb.org/manual/core/map-reduce/
现在我们已经了解了所有的声明和警告:下面的 AF shell 命令将使用相同的 id 正确计算所有内容: db.collection.aggregate({$unwind:"$list"}, {$group: {_id: "$list.id", count:{$sum:1}}}) 此命令按列表汇总集合中不同文档的数量。不幸的是,C 驱动程序没有聚合助手命令。需要使用 mongo_run_command 函数来运行聚合。请注意,这只能返回 bson 文档而不是游标;因此结果仅限于文档大小限制(Mongo 2.5.3, 16Megs)。这两个 C 示例在 subdoc 上求和,作为一个整体用于相等目的,因此对于这些排序问题。您需要添加 .
这是使用 BCON 的示例(http://api.mongodb.org/c/current/bcon.html),推荐的易于使用的方法(它比示例二慢 10%):
#include <mongo.h>
#include <bcon.h>
#include <stdio.h>
int main() {
/*
* We assume objects in the form of {_id:<any_id>, list:[{a:<int>,b:<int>}, ...]}
*/
char table[] = "agg";
mongo conn[1];
mongo_init(conn);
if(MONGO_OK != mongo_client(conn, "127.0.0.1", 27017))
return 1;
bson b[1], b_result[1];
/*create the aggregation command in bson*/
bcon cmd_aggregate[] = { "aggregate", BRS(table),
"pipeline",
"[",
"{",
"$unwind", "$list",
"}",
"{",
"$group",
"{",
"_id", "$list",
"distinct_count",
"{",
"$sum", BI(1),
"}",
"}",
"}",
"]",
BEND
};
bson_from_bcon(b, cmd_aggregate);
/*So you can see your command*/
bson_print(b);
/*run the command*/
mongo_run_command(conn, "test", b, b_result);
/*command results*/
bson_print(b_result);
bson_destroy(b_result);
bson_destroy(b);
mongo_destroy(conn);
return 0;
}
这是稍快的样式:
#include <mongo.h>
#include <stdio.h>
int main() {
/*
* We assume objects in the form of {_id:<any_id>, list:[{a:<int>,b:<int>}, ...]}
*/
char table[] = "agg";
mongo conn[1];
mongo_init(conn);
if(MONGO_OK != mongo_client(conn, "127.0.0.1", 27017))
return 1;
bson b[1], b_result[1];
/*create the aggregation command in bson*/
bson_init(b);
bson_append_string(b, "aggregate", "agg");
bson_append_start_array(b, "pipeline");
bson_append_start_object(b,"0");
bson_append_string(b, "$unwind", "$list");
bson_append_finish_object(b);
bson_append_start_object(b,"1");
bson_append_start_object(b,"$group");
bson_append_string(b,"_id", "$list");
bson_append_start_object(b, "_count");
bson_append_int(b, "$sum", 1);
bson_append_finish_object(b);
bson_append_finish_object(b);
bson_append_finish_object(b);
bson_append_finish_array(b);
bson_finish(b);
/*So you can see your command*/
bson_print(b);
/*run the command*/
mongo_run_command(conn, "test", b, b_result);
/*command results*/
bson_print(b_result);
bson_destroy(b_result);
bson_destroy(b);
mongo_destroy(conn);
return 0;
}
最后但同样重要的是,在 shell 中连接数据库,然后运行以下命令将允许您查看查询(如果您直接从命令行启动数据库并且没有分叉它,您可以在该终端中看到它们):
use admin
db.runCommand( { setParameter: 1, logLevel: 1 } )
这对于调试您认为要发送到数据库的命令很有用。它在该终端中的外观应该与您在 mongo shell 中创建的相同。
希望这涵盖了您问题的所有方面。需要帮助请叫我。
最好的,查理