2013-03-06 60 views
4

我正在为我一直在使用的MongoDB准备一个描述性的“模式”(quelle horreur)。清单,计算所有键上唯一的MongoDB值的因子

我用优秀的variety.js来创建所有键的列表并显示每个键的覆盖范围。但是,如果与键对应的值有一组值,我希望能够将整个集列为“可用值”。在R中,我会将这些作为分类变量的“因素”,即性别:[“M”,“F”]。我知道我可以只使用R + RMongo,查询每个变量,基本上做同样的过程,我会创建一个直方图,但我想知道适当的Mongo.query()/ javascript/Map,减少方法来解决这个问题。我明白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个值)。

+0

{“key1”:{[“value1”,“value2”]}}不是有效的JSON。 每个数组都必须有一个名称。在此代码中,key1是包含无名数组的对象的名称。最正确的方法是给一个数组的名称: {“key1”:{anArray:[“value1”,“value2”]}} – 2013-03-14 01:28:32

+1

好吧,我拿走了一层嵌套。谢谢。 – Mittenchops 2013-03-14 13:45:55

+0

你是否假设所有字段都是顶级简单字段?不担心数组或嵌入式json文档? – 2013-04-28 21:32:27

回答

1

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

这里是它可能看起来像在JS中,如果传递一个名为“keys”的数组,其中有几个非 - “_ id”命名字段(我假设顶级字段,并且你不关心数组,嵌入文件等)。

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 
}