我正在尝试聚合博客上所有相互回复的用户的名称。我的记录如下:
{
"_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
}
}