我正在尝试用Erlang在Riak上做mapreduce。我有以下数据:
Bucket = "Numbers"
{Keys,values} = {Random key,1},{Random key,2}........{Random key,1000}.
现在,我存储1000个值,从1到1000,其中所有键都是由作为参数给定的术语undefined自动生成的,因此所有键的值都从1到1000开始。
所以我希望数据只来自偶数值。使用mapreduce,我该如何实现?
答案 0 :(得分:0)
您将按照http://docs.basho.com/riak/latest/dev/advanced/mapreduce/
中的描述构建阶段函数一种可能的地图功能:
Mapfun = fun(Object, _KeyData, _Arg) ->
%% get the object value, convert to integer and check if even
Value = list_to_integer(binary_to_term(riak_object:get_value(Object))),
case Value rem 2 of
0 -> [Value];
1 -> []
end
end.
虽然您可能希望在遇到兄弟姐妹的情况下不会完全失败:
Mapfun = fun(Object, _KeyData, _Arg) ->
Values = riak_object:get_values(Object),
case length(Values) of %% checking for siblings
1 -> %% only 1 value == no siblings
I = list_to_integer(binary_to_term(hd(Values))),
case I rem 2 of
0 -> [I]; %% value is even
1 -> [] %% value is odd
end;
_ -> [] %% What should happen with siblings?
end
end.
您可能还需要阻止或检查以下其他情况:包含非数字字符的值,空值,已删除的值(tombsones),仅举几例。
编辑:
需要注意的是:执行全桶MapReduce作业需要Riak读取磁盘中的每个值,这可能会导致极大的延迟和超大数据集的超时。可能不是你想要在制作中做的事情。
<小时/> 完整的MapReduce示例(出于空间考虑,限制为1到200):
假设您克隆并构建了riak-erlang-client 使用上面的第二个Mapfun
erl -pa {path-to-riak-erlang-client}/ebin
定义reduce函数以对列表进行排序
Reducefun = fun(List,_) ->
lists:sort(List)
end.
附加到本地Riak服务器
{ok, Pid} = riakc_pb_socket:start_link("127.0.0.1", 8087).
生成一些测试数据
[ riakc_pb_socket:put(
Pid,
riakc_obj:new(
<<"numbers">>,
list_to_binary("Key" ++ V),V
)
) || V <- [ integer_to_list(Itr) || Itr <- lists:seq(1,200)]],
使用此客户端执行MapReduce的功能是
mapred(pid(), mapred_inputs(), [mapred_queryterm()])
mapred_queryterm
是readme中定义的{Type, FunTerm, Arg, Keep}
形式的阶段规范列表。对于此示例,有两个阶段:
{map, Mapfun, none, true}
{reduce, Reducefun, none, true}
执行MapReduce查询
{ok,Results} = riakc_pb_socket:mapred(
Pid, %% The socket pid from above
<<"numbers">>, %% Input is the bucket
[{map,{qfun,Mapfun},none,true},
{reduce,{qfun,Reducefun},none,true}]
),
Results
将是[{_Phase Index_, _Phase Output_}]
的列表,其中Keep
为真的每个阶段都有单独的条目,在此示例中,两个阶段都标记为keep,因此在此示例中{{ 1}}将是
Results
打印出每个阶段的结果:
[{0,[_map phase result_]},{1,[_reduce phase result_]}]
当我跑这个时,我的输出是:
[ io:format("MapReduce Result of phase ~p:~n~P~n",[P,Result,500])
|| {P,Result} <- Results ].