我在这里混淆的主要问题(我认为)是qfun的参数应该是什么以及返回值应该是什么。 README基本上没有说明这一点,它给出的例子抛弃了第二和第三个args。
现在我只是想了解这些论点,而不是将Riak用于任何实际的事情。最终,我将尝试用它来重建我们(基于MySQL的慢速)财务报告系统。所以在这里忽略了我的目标的无意义,为什么以下给我一个badfun
例外?
数据只是名称和年龄的元组(对),键是名称。在从Erlang控制台插入数据之前,我没有进行任何JSON等转换。
现在{Name, Age}
中存储了一些<<"people">>
对,我想使用MapReduce(除了理解“如何”之外没有其他理由)将值恢复,在第一次使用时保持不变。 / p>
riakc_pb_socket:mapred(
Pid, <<"people">>,
[{map, {qfun, fun(Obj, _, _) -> [Obj] end}, none, true}]).
然而,这只是给了我一个坏蛋:
{error,<<"{\"phase\":0,\"error\":\"{badfun,#Fun<erl_eval.18.17052888>}\",\"input\":\"{ok,{r_object,<<\\\"people\\\">>,<<\\\"elaine\\\">"...>>}
如何通过我的map函数传递数据不变?有没有比README更好的Erlang客户端文档? README似乎假设您已经知道输入是什么。
答案 0 :(得分:1)
有2个Riak Erlang客户端用于不同目的。
第一个是riak_kv模块(riak_client.erl和riak_object.erl)中包含的内部Riak客户端。如果您连接到Riak控制台或者正在编写MapReduce函数或提交挂钩,则可以使用此方法。因为它是从Riak节点内运行的,所以它与qfuns一起运行良好。
另一个客户端是外部应用程序使用的官方Riak client for Erlang,通过协议缓冲区接口连接到Riak。这就是您在上面的示例中使用的内容。当这通过协议缓冲区连接时,通常建议编译Erlang中的MapReduce函数并deployed on the nodes of the cluster as named functions。这也可以从其他客户端库访问它们。
答案 1 :(得分:0)
我认为我的代码实际上是正确的,我的问题在于我正在尝试使用shell来执行代码。我需要实际编译代码才能在Riak中运行。这是Erlang shell的限制以及编译乐趣的方式。
答案 2 :(得分:0)
经过几天的游戏,这里有一个巧妙的技巧,使开发更容易。利用Erlang的RPC支持以及加载运行时代码的事实,在所有Riak节点上分发代码:
%% Call this somewhere during your app's initialization routine.
%% Assumes you have a list of available Riak nodes in your app's env.
load_mapreduce_in_riak() ->
load_mapreduce_in_riak(application:get_env(app_name, riak_nodes, [])).
load_mapreduce_in_riak([]) ->
ok;
load_mapreduce_in_riak([{Node, Cookie}|Tail]) ->
erlang:set_cookie(Node, Cookie),
case net_adm:ping(Node) of
pong ->
{Mod, Bin, Path} = code:get_object_code(app_name_mapreduce),
rpc:call(Node, code, load_binary, [Mod, Path, Bin]);
pang ->
io:format("Riak node ~p down! (ping <-> pang)~n", [Node])
end,
load_mapreduce_in_riak(Tail).
现在您可以参考模块app_name_mapreduce
中的任何功能,它们将对Riak群集可见。如果需要,可以使用代码:delete / 1再次删除代码。