4

我正在为我一直在使用的 MongoDB 准备一个描述性的“模式”(quelle horreur)。

我使用出色的variety.js创建了所有键的列表并显示每个键的覆盖范围。但是,如果与键对应的值具有一小组值,我希望能够将整个集合列为“可用值”。在 R 中,我会将这些视为分类变量的“因素”,即性别:[“M”、“F”]。

我知道我可以只使用 R + RMongo,查询每个变量,并且基本上执行与创建直方图相同的过程,但我想知道正确的 Mongo.query()/javascript/Map,Reduce 方法这个。我了解 db.collection.aggregate() 函数正是为此而设计的。

在问这个之前,我参考了:

但不能完全正确地获得管道顺序。因此,例如,如果我有这样的文件:

{_id : 1, "key1" : "value1", "key2": "value3"}
{_id : 2, "key1" : "value2", "key2": "value3"}

我想返回类似的东西:

{"key1" : ["value1", "value2"]}
{"key2" : ["value3"]}

或者更好,计数:

{"key1" : ["value1" : 1, "value2" : 1]}
{"key2" : ["value3" : 2]}

我认识到这样做的一个问题是任何具有各种不同值的值——例如,文本字段或连续变量。理想情况下,如果有超过 x 个不同的可能值,最好截断,比如不超过 20 个唯一值。如果我发现它实际上更多,我会直接查询该变量。

这是不是这样的:

db.collection.aggregate(
   {$limit: 20,
    $group: {
        _id: "$??varname",
        count: {$sum: 1}
   }})

首先,我怎样才能引用 ??varname?每个键的名称?

我看到了这个有 95% 的链接: Binning and tabulate (unique/count) in Mongo

和...

input data:

{ "_id" : 1, "age" : 22.34, "gender" : "f" }
{ "_id" : 2, "age" : 23.9, "gender" : "f" }
{ "_id" : 3, "age" : 27.4, "gender" : "f" }
{ "_id" : 4, "age" : 26.9, "gender" : "m" }
{ "_id" : 5, "age" : 26, "gender" : "m" }

这个脚本:

db.collection.aggregate(
   {$project: {gender:1}},
   {$group: {
        _id: "$gender",
        count: {$sum: 1}
   }})

产生:

{"result" : 
   [
     {"_id" : "m", "count" : 2},
     {"_id" : "f", "count" : 3}
   ],
   "ok" : 1
}

但是我不明白的是,对于具有可能大量返回值的未知数量/名称的键,我如何一般地执行此操作?此示例知道键名称是性别,并且响应集很小(2 个值)。

4

1 回答 1

1

如果您已经运行了输出集合中所有键名称的脚本,则可以动态生成聚合框架管道。这意味着要么扩展variety.js 类型脚本,要么只是编写你自己的。

如果传递一个名为“keys”的数组,它有几个非“_id”命名字段(我假设顶级字段并且你不关心数组、嵌入文档等),这就是它在 JS 中的样子.

keys = ["key1", "key2"];
group = { "$group" : { "_id" : null } } ;
keys.forEach( function(f) {
     group["$group"][f+"List"] = { "$addToSet" : "$" + f };  } );
db.collection.aggregate(group);
{
    "result" : [
        {
            "_id" : null,
            "key1List" : [
                "value2",
                "value1"
            ],
            "key2List" : [
                "value3"
            ]
        }
    ],
    "ok" : 1
}
于 2013-04-28T21:47:08.743 回答