如何在MongoDB中对大型数组进行聚合?

18
我有一个大约400GB的MongoDB数据库,文件包含各种字段,但关键是一个ID数组。
因此,一个JSON文件可能看起来像这样:
{
 "name":"bob"
 "dob":"1/1/2011"
 "key":
      [  
       "1020123123",
       "1234123222",
       "5021297723"
      ]
}

这里的关键变量是“key”。总共有大约100亿个键在5000万个文档中(因此每个文档大约有200个键)。键可以重复,而独特的键约有1500万个。

我想做的是返回出现最频繁的10,000个键。我认为聚合操作可能能够实现这一点,但我很难让它运行起来。以下是我的代码:

db.users.aggregate( 
 [ 
  { $unwind : "$key" }, 
  { $group : { _id : "$key", number : { $sum : 1 } } },
  { $sort : { number : -1 } }, 
  { $limit : 10000 }
 ] 
);

有什么想法我做错了什么吗?


你遇到了什么问题?你的MongoDB版本是多少? - Wizard
我正在运行2.6.4版本。我遇到的错误是$group的内存限制超出了。 - AlexKogan
1个回答

48

试一下这个:

db.users.aggregate( 
 [ 
  { $unwind : "$key" }, 
  { $group : { _id : "$key", number : { $sum : 1 } } },
  { $sort : { number : -1 } }, 
  { $limit : 10000 },
  { $out:"result"},
 ], {
  allowDiskUse:true,
  cursor:{}
 }
);

然后通过 db.result.find() 查找结果。


3
我尝试了这个,但是出现了错误:"exception: Exceeded memory limit for $group, but didn't allow external sort. Pass allowDiskUse:true to opt in." 这很奇怪,因为我认为我已经使用了你代码的第二部分来选择了 "opt in"。嗯嗯。 - AlexKogan
@AlexKogan,这真的很奇怪。你能在这里粘贴你的代码吗? - Wizard
1
这里是!db.users.aggregate( [ { $unwind : "$likes" }, { $group : { _id : "$likes", number : { $sum : 1 } } }, { $sort : { number : -1 } }, { $limit : 10000 }, { $out:"result"}, ], { allowDiskUse:true, cursor:{} } ) - AlexKogan
非常奇怪!我正在使用Robomongo连接到我的远程服务器。我检查了MongoDB的版本,它是2.6.4。除非Robomongo本身很旧? - AlexKogan
@AlexKogan,是可以的。服务器应该是V2.6.0+,否则它不会返回异常信息。我在mongo shell V2.4.8中键入db.c.aggregate来检查其js代码,并发现它只接受第一个参数,如果第一个参数是数组类型。您可以使用最新的robomongo或mongo shell V2.6.4进行测试。 - Wizard
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接