2013-09-12 3 views
0

Если бы я хотел посчитать foobar.relationships.friend.count, как бы я использовать карту/уменьшить против этого документа структуры, так что счетчик будет равен 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 
        } 
       } 
      } 
     } 
    } 
] 

ответ

-1

Я думаю, вам будет нужен собственный inputreader. Этот сайт дает вам урок, как это можно сделать: http://bigdatacircus.com/2012/08/01/wordcount-with-custom-record-reader-of-textinputformat/

Затем запустить MapReduce с картографа

Mapper<LongWritable, ClassRepresentingMyRecords, Text, IntWritable> 

В вашей функции карты вы извлечь значение для подсчета и испускать это значение. Не уверен, нужен ли вам ключ?

В редукторе вы объединяете все элементы с одним и тем же ключом (= «счет» в вашем случае).

Это, должно быть, должно быть на вашем пути, я думаю.

+0

Im пытается сделать это в rethinkdb –

+0

Ok извините, может быть, отметить, что в этом вопросе, я вижу, вы добавили тег, но я должен пропустить это .. – DDW

+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.

Ex:

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 
+0

Ваш метод уменьшения карты не работает. По последнему предложению у вас есть дополнительные '}' и ','. Я получаю 'ArgumentError: [] не может обрабатывать var_14 типа RethinkDB :: RQL' –

+0

Err, есть ошибка в рубиновом драйвере - см. Https://github.com/rethinkdb/rethinkdb/issues/1432 для отслеживания прогресса. – neumino

+0

Просто обновил запросы. Использование '.get_field()' вместо '[]' должно работать сейчас. – neumino