0

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

2 回答 2

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
于 2013-09-12T20:18:26.633 回答
-1

我认为您将需要自己的输入阅读器。该站点为您提供了如何完成的教程:http: //bigdatacircus.com/2012/08/01/wordcount-with-custom-record-reader-of-textinputformat/

然后你用映射器运行 ​​mapreduce

Mapper<LongWritable, ClassRepresentingMyRecords, Text, IntWritable>

在您的 map 函数中,您提取 count 的值并发出这是该值。不确定是否需要钥匙?

在减速器中,您将具有相同键的所有元素(在您的情况下为 ='count')相加。

我认为这应该会让你走上你的路。

于 2013-09-12T12:46:08.313 回答