如果我想计算foobar.relationships.friend.count,我将如何对这个文档结构使用map / reduce,这样计数将等于22。
[
[0] {
"rank" => nil,
"profile_id" => 3,
"20130913" => {
"foobar" => {
"relationships" => {
"acquaintance" => {
"count" => 0
},
"friend" => {
"males_count" => 0,
"ids" => [],
"females_count" => 0,
"count" => 10
}
}
}
},
"20130912" => {
"foobar" => {
"relationships" => {
"acquaintance" => {
"count" => 0
},
"friend" => {
"males_count" => 0,
"ids" => [
[0] 77,
[1] 78,
[2] 79
],
"females_count" => 0,
"count" => 12
}
}
}
}
}
]
答案 0 :(得分:1)
在JavaScript中,此查询可以获得您期望的结果
r.db('test').table('test').get(3).do( function(doc) {
return doc.keys().map(function(key) {
return r.branch(
doc(key).typeOf().eq('OBJECT'),
doc(key)("foobar")("relationships")("friend")("count").default(0),
0
)
}).reduce( function(left, right) {
return left.add(right)
})
})
在Ruby中,它应该是
r.db('test').table('test').get(3).do{ |doc|
doc.keys().map{ |key|
r.branch(
doc.get_field(key).typeOf().eq('OBJECT'),
doc.get_field(key)["foobar"]["relationships"]["friend"]["count"].default(0),
0
)
}.reduce{ |left, right|
left+right
}
}
我也倾向于认为你使用的架构并没有真正适应,最好使用像
这样的东西{
rank: null
profile_id: 3
people: [
{
id: 20130913,
foobar: { ... }
},
{
id: 20130912,
foobar: { ... }
}
]
}
编辑:在不使用r.branch
的情况下执行此操作的更简单方法就是使用without
命令删除不是对象的字段。
例如:
r.db('test').table('test').get(3).without('rank', 'profile_id').do{ |doc|
doc.keys().map{ |key|
doc.get_field(key)["foobar"]["relationships"]["friend"]["count"].default(0)
}.reduce{ |left, right|
left+right
}
}.run
答案 1 :(得分:-1)
我认为你需要自己的输入阅读器。该网站为您提供了如何完成的教程:http://bigdatacircus.com/2012/08/01/wordcount-with-custom-record-reader-of-textinputformat/
然后使用mapper运行mapreduce
Mapper<LongWritable, ClassRepresentingMyRecords, Text, IntWritable>
在地图功能中,您提取count的值,并发出这是值。不确定你是否需要钥匙?
在reducer中,您将所有元素与相同的键一起添加(在您的情况下为''count')。
这应该让你按照自己的方式行事。