我有以下记录:
{ "_id" : ObjectId("55889370ba09474fd178d8b8"), "url" : "http://stackoverflow.com/questions/ask"}
{ "_id" : ObjectId("55889370ba09474fd178d8b4"), "url" : "http://stackoverflow.com"}
{ "_id" : ObjectId("55889370ba09474fd178d8b2"), "url" : "http://espn.com"}
我想做一个聚合来获取每个站点的计数。基本上我希望前两个记录都属于同一个组(它们具有相同的根)。
我创建了一个用户定义的函数来将url转换为其根。我的想法是使用用户定义的函数首先投影记录(更改网址字段),然后按网址分组。问题是显然用户定义的功能不能用于聚合。它们可以用在投影中的where子句中,但是可以在聚合中使用where子句进行投影。
我有什么方法可以进行我需要的聚合吗?
编辑:
也许为了让这个例子更具说明性,我应该补充说,如果我想通过根网站分组并计算它们,我会得到类似的结果:
{ "_id" : "http://stackoverflow.com", "count" : 2}
{ "_id" : "http://espn.com", "count" : 1}
答案 0 :(得分:1)
汇总时尝试使用regex。您可以为此目的跳过用户定义的函数。
例如,question使用它。
在您的特定情况下,描述了一种解决方法here。不确定这是不是你想要的。
否则,我担心你必须映射 - 减少它。
答案 1 :(得分:1)
这是一个简单的解决方案。示例数据是:
> db.test.find()
{ "_id" : ObjectId("559178703535798edab41c36"), "text" : "aaaasfadf" }
{ "_id" : ObjectId("559178743535798edab41c37"), "text" : "bfasdfasdf" }
{ "_id" : ObjectId("559178783535798edab41c38"), "text" : "aasdfsdf" }
{ "_id" : ObjectId("5591787b3535798edab41c39"), "text" : "asdf" }
{ "_id" : ObjectId("5591787e3535798edab41c3a"), "text" : "csfd" }
我想根据字符串的第一个字母对项目进行分组(在此处放置提取URL基础的函数):
db.test.group({
$keyf : function(doc){
return {
key : doc.text.substring(0,1) // extract URL base here
}
},
$reduce : function(curr, result){
result.count++
},
initial : {
count: 0
}
})
结果是:
[
{
"key" : "a",
"count" : 3
},
{
"key" : "b",
"count" : 1
},
{
"key" : "c",
"count" : 1
}
]