2015-06-29 44 views
1

我有以下记录:MongoDB:在聚合中使用用户定义函数的任何方式?

{ "_id" : ObjectId("55889370ba09474fd178d8b8"), "url" : "http://stackoverflow.com/questions/ask"} 
{ "_id" : ObjectId("55889370ba09474fd178d8b4"), "url" : "http://stackoverflow.com"} 
{ "_id" : ObjectId("55889370ba09474fd178d8b2"), "url" : "http://espn.com"} 

我想要做的聚合,他们的根来获得每个站点的数量。基本上我希望前两个记录都属于同一组(它们具有相同的根)。

我创建了一个用户定义的函数来将url转换为其根。我的想法是使用用户定义的函数来首先投影记录(更改url字段),然后通过url进行分组。问题是显然用户定义的函数不能用于聚合。它们可用于投影中的where子句,但用where子句投影时不能用于聚合。

有什么办法可以聚合我需要的吗?

编辑:

也许使例子更能说明我要补充一点,如果我如想组由根网站,并指望他们,我会得到这样的:

{ "_id" : "http://stackoverflow.com", "count" : 2} 
{ "_id" : "http://espn.com", "count" : 1} 
+0

你基本上是在寻找使用**'$ regex' **的**'$ project' **过滤器,但是目前聚合框架没有这个功能,这里有一个开放的JIRA [*] * SERVER-11947 **](https://jira.mongodb.org /浏览/ SERVER-11947)。 – chridam

+0

那么目前没有办法做到这一点?没有其他的选择? –

+0

这不适合http://stackoverflow.com/a/16252753/4573999? –

回答

1

尝试聚合时使用regex。我想可能会跳过用户定义的函数。

这个question例如使用它。

在您的特定情况下,解决方法描述为here。不知道这是你想要的。

否则恐怕你必须映射 - 减少它。

+1

这不是在匹配子句中使用的正则表达式吗?我不想过滤任何记录。我只是想在投影过程中改变场,以便在分组过程中可以使用同一个键。 –

+0

是的,但我想这也许是个有趣的解决方法:http://stackoverflow.com/a/17493547/1566187你能证实吗?否则,只需使用map-reduce我会说。 – Elyasin

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 
    } 
]