按字段的一部分进行分组/计数

时间:2014-04-13 11:27:57

标签: javascript mongodb mapreduce aggregation-framework

我有一个像这样的集合

{"foo" : "abc-123", more fields.... }
{"foo" : "abc-456", more fields.... }
{"foo" : "cde-000", more fields.... }
{"foo" : "cde-555", more fields.... }
{"foo" : "else-9991234", more fields.... }

并希望按foo的第一部分进行分组和计数:

{
    "abc": 2,
    "cde": 2,
    "else": 1
}

我考虑过使用聚合框架,但我不确定如何提取第一部分:

myColl.aggregate([
     $project: { firstPart: { ???? '$foo' 

2 个答案:

答案 0 :(得分:1)

我不确定这是否可以与mongo一起使用。最终你必须在第一部分拆分字符串和组。

如果我是你,我宁愿修改你的架构来添加新字段foo1,这将是字符串的第一部分。您可以使用foreach

执行此操作
db.collection.find().forEach(function(el){
  // here split your el['foo'] and update the el with new `foo1` which will have your first part
})

之后,您可以轻松使用聚合框架。

答案 1 :(得分:1)

很遗憾你需要像这样拆分,否则你可能会在聚合管道中使用$ substr运算符。

但是由于你需要这个功能,你可以使用mapReduce:

db.collection.mapReduce() {
    function() {
        var parts = this.foo.split("-");
        emit( parts[0], 1 );
    },
    function(key,values){
        return values.length;
    },
    { "out": { "inline": 1 } }
)

发送到reducer的任何内容都会计算数组中的“值”,只有一个键的任何东西都会绕过reducer,但我们已经返回了1的计数。