在MongoDB MapReduce中访问关联数组/对象



我正在尝试聚合博客上所有相互回复的用户的名称。我的记录如下:

{
    "_id" : ObjectId("4ee9ada4edfb941f3400ba63"),
    "thread" : "Millenium - Niels Arden Oplev",
    "author" : "kilny17",
    "parent_count" : 0,
    "parents" : [ ],
    "child_count" : 2,
    "date" : ISODate("2010-04-20T21:14:00Z"),
    "message" : "I don't think so...",
    "children" : [
            {
                    "date" : ISODate("2010-04-20T21:21:00Z"),
                    "author" : "Kissoon"
            },
            {
                    "date" : ISODate("2010-04-20T21:49:00Z"),
                    "author" : "Twain"
            }
    ]
}

我试图为每个作者返回一个MapReduced对象,例如:

{ "_id" : "kilny17",
"value" : { 
    "author" : "kilny17", 
    "connections" : {
          "Kissoon" : 1, 
          "Twain" : 1 }
    } 
}

此代码适用于每个只有1个子元素的子元素的记录,但不适用于更多的记录:

    function mapf()
    {   
        var count = this['child_count'];
        if (count > 0){
            var m_author = this.author;
            this['children'].forEach( function(c){
                    var connect = {'name':c['author'], 'appears':1};
                    emit(m_author, {'author':m_author, 'connections':connect});                   
            });
        };           
    }
    function reducef(key, values)
    {   
        var connects = new Object();          
        var r = {'author':key, 'connections':connects, 'weight':0};
        values.forEach(function(v)
        {   
            c_name = v['connections'].name;
            if (c_name == null)
                c_name = 'Null_name';
            if (r['connections'][c_name] != null)
                r['connections'][c_name] += v['connections']['appears'];
            else
                r['connections'][c_name] = v['connections']['appears'];
        });
       return r;        
    }

对于任何有一个以上孩子的记录(例如给定的例子),都找不到作者的名字,我得到了一个这样的精简记录(注意:kilny有另一篇关于孩子DarkKnight3657的帖子):

 { "_id" : "kilny17", "value" : { "author" : "kilny17", "connections" : { "DarkKnight3657" : 1, "Null_name" : null } } }

有人知道为什么没有从对象中读取作者的名字吗?

感谢

我认为问题在于您没有在映射器中将connections定义为数组,而是将其定义为元素。在我的脑海中,它似乎应该写着:

var connect = [{'name':c['author'], 'appears':1}];
emit(m_author, {'author':m_author, 'connections':connect});

正如Chris所建议的,我使用的解决方案是将对象更改为数组:

    function mapf()
    {   
        if (this['child_count'] > 0){
            var m_author = this.author;
            if ( m_author == '')
                m_author = 'Unknown_author';
            var connect = [];
            var weight = 0;
            for ( c in this['children'] ){
                c_name =  this['children'][c]['author'];
                found = false;
                for (i in connect){
                    if (connect[i]['name'] == c_name){
                        connect[i]['appears'] += 1;
                        found = true;
                    }
                }
                if (found == false){
                   var con = {'name':c_name,'appears':1};
                   connect.push(con);
                }
                weight += 1;
            };       
            emit(m_author, {'author':m_author, 'connections':connect, 'weight':weight});
        };
    }
    function reducef(key, values)
    {   
        var r = {'author':key, 'connections':[], 'weight':0};
        values.forEach(function(v)
        {   
            for ( c in v['connections'] ){
                c_name =  v['connections'][c]['name'];
                found = false;
                for (i in r['connections']){
                    if (r['connections'][i]['name'] == c_name){
                        r['connections'][i]['appears'] += 1;
                        found = true;
                    }
                }
                if (found == false){
                   var con = {'name':c_name,'appears':1};
                   r['connections'].push(con);
                }
            };
            r.weight += v.weight;
        });
       return r;
    }

这就产生了所需类型的记录:

{
    "_id" : "Skaundee",
    "value" : {
            "author" : "Skaundee",
            "connections" : [
                    {
                            "name" : "Carnage",
                            "appears" : 1
                    },
                    {
                            "name" : "Tree",
                            "appears" : 1
                    }
            ],
            "weight" : 2
    }
}

相关内容

  • 没有找到相关文章

最新更新