Mapreduce 您将如何在此文档结构上使用map reduce?

Mapreduce 您将如何在此文档结构上使用map reduce?,mapreduce,rethinkdb,rethinkdb-ruby,Mapreduce,Rethinkdb,Rethinkdb Ruby,如果我想计算foobar.relationships.friend.count,我将如何对该文档结构使用map/reduce,使计数等于22 [ [0] { "rank" => nil, "profile_id" => 3, "20130913" => { "foobar" => { "relationships" => {

如果我想计算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
                    }
                }
            }
        }
    }
]

我想你需要自己的输入头。本网站为您提供了一个如何进行此操作的教程:

然后使用映射器运行mapreduce

Mapper<LongWritable, ClassRepresentingMyRecords, Text, IntWritable>
Mapper
在map函数中,提取count的值,然后发射该值。不确定你是否需要钥匙

在reducer中,使用相同的键(=在您的情况下为“count”)将所有元素相加


我想,这应该会让你走上正轨。

在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
命令删除不是对象的字段

例:


我试图在RejectionDBOK中这样做对不起,可能在问题中提到,我看到你添加了标记,但我一定错过了。链接已断开。你的map reduce方法不起作用。在最后一个建议中,您有一个额外的
}
和一个
。我得到
ArgumentError:[]无法处理REJECTDB::RQL类型的var_14
Err,ruby驱动程序中有一个bug——请参阅跟踪进度。刚刚更新了查询。使用
.get_field()
而不是
[]
现在应该可以工作了。
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