MongoDB:在聚合中使用用户定义函数的任何方法?

时间:2015-06-29 14:24:43

标签: mongodb aggregation-framework

我有以下记录:

{ "_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}

2 个答案:

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