Riak MapReduce с использованием JavaScript и Python-клиента - PullRequest
0 голосов
/ 04 ноября 2018

Настройка

Рассмотрим простую базу данных значений ключей Riak, содержащую название города и несколько тегов, связанных с городом. Я использую клиент Python 3 для создания корзины и добавления данных:

import riak

client = riak.RiakClient(pb_port=8087, protocol='pbc')
bucket = client.bucket('cities')

# Adding data to the bucket
bucket.new('tallinn', {'name': 'Tallinn', 'tags': ['architecture', 'food',  'port', 'forest']}).store()
bucket.new('riga', {'name': 'Riga', 'tags': ['food', 'architecture', 'forest']}).store()
bucket.new('vilnius', {'name': 'Vilnius', 'tags': ['beer', 'food', 'shopping']}).store()
bucket.new('kiev', {'name': 'Kiev'}).store()

Тогда я могу проверить, что внутри ведра, вот так:

keys = client.get_keys(bucket)  # Get all keys from bucket
print('Keys:', keys)
for key in keys:
    article = bucket.get(key).data  # Get data by key from bucket
    print(article)
print(type(article))  # Check what is the type of object I get

Выход:

Keys: ['tallinn', 'riga', 'kiev', 'vilnius']
{'name': 'Tallinn', 'tags': ['architecture', 'food', 'port', 'forest']}
{'name': 'Riga', 'tags': ['food', 'architecture', 'forest']}
{'name': 'Kiev'}
{'name': 'Vilnius', 'tags': ['beer', 'food', 'shopping']}
<class 'dict'>

Как видите, я получаю то, что даю. И поскольку тип объектов по-прежнему является словарем <class 'dict'>, я могу легко получить доступ к любой части данных.

Вопрос

Из этих данных, используя MapReduce, я хочу получить популярность каждого тега, появляющегося в данных. Как отсортированный список кортежей или списков:

[(3, 'food'), (2, 'forest'), (2, 'architecture'), (1, 'shopping'), (1, 'port'), (1, 'beer')]

MapReduce

Используя следующий код, я могу получить список тегов для каждой пары ключ-значение:

query = client.add('cities')

# Javascript functions for Map phase and Reduce phace
js_func_map = "function(v) {var val = JSON.parse(v.values[0].data);"\
              "return[val.tags];}"
js_func_reduce = "function(values) {return values;}"

query.map(js_func_map)  # Add Javascript function to Map phase
query.reduce(js_func_reduce)  # Add Javascript function to Reduce phase

# Get result form query
for result in query.run():
    print(result)

Однако это все еще далеко от того, что я намереваюсь:

['bear', 'architecture', 'forest']
None
['architecture', 'food', 'port', 'forest']
['bear', 'food', 'shopping']
...