我正在做riak-erlang客户端。在执行Mapreduce时,我得到了以下输出:
现在我想从我得到的结果集中获得数据。我想要age/name,也想通过特定的name得到age
我怎么能那样做呢?请帮帮我
{ok,[{0,R}]} = riakc_pb_socket:mapred(Pid,<<"test">>,[{map,{qfun,Mapf},none,true}]).
{ok,[{0,
[<<"{"age": 24, "name": "krishna"}">>,
<<"{"age": 29, "name": "sharat"}">>,
<<"{"age": 25, "name": "ramesh"}">>,
<<"{"age": 28, "name": "kumar"}">>,
<<"{"age": 24, "name": "gopi"}">>,
<<"{"age": 27, "name": "anil"}">>]}]}
:年龄:24
或
name: "krishna"
或者如果我给出名字:krishna
age:24
如何获取数据
基本上,你得到json编码的数据,所以首先你需要解码它,然后实现一些过滤/查找机制。我的方法是使用jiffy json解析器:
首先,克隆并构建jiffy:
git clone git@github.com:davisp/jiffy.git;
cd jiffy; make
您必须在运行erlang命令行客户端时将jiffy添加到代码路径:
erl -pa Private/jiffy/ebin -pa Private/jiffy/deps
最后是基于name获取年龄的实现:
-module(test).
-compile(export_all).
decode(Results) ->
[jiffy:decode(E)||E<-Results].
get_age(_, []) ->
erlang:throw(name_not_found);
get_age(Name, [{H}|T]) ->
case proplists:get_value(<<"name">>, H) of
Name -> proplists:get_value(<<"age">>, H);
_ -> get_age(Name, T)
end.
用法:
erl -pa Private/jiffy/ebin -pa Private/jiffy/deps
Erlang R16B03 (erts-5.10.4) [source] [64-bit] [smp:8:8] [async-threads:10] [hipe] [kernel-poll:false]
Eshell V5.10.4 (abort with ^G)
1> application:start(jiffy).
ok
2> c(test).
{ok,test}
3> {ok, [{0, Results}]} = {ok,[{0,
3> [<<"{"age": 24, "name": "krishna"}">>,
3> <<"{"age": 29, "name": "sharat"}">>,
3> <<"{"age": 25, "name": "ramesh"}">>,
3> <<"{"age": 28, "name": "kumar"}">>,
3> <<"{"age": 24, "name": "gopi"}">>,
3> <<"{"age": 27, "name": "anil"}">>]}]}.
{ok,[{0,
[<<"{"age": 24, "name": "krishna"}">>,
<<"{"age": 29, "name": "sharat"}">>,
<<"{"age": 25, "name": "ramesh"}">>,
<<"{"age": 28, "name": "kumar"}">>,
<<"{"age": 24, "name": "gopi"}">>,
<<"{"age": 27, "name": "anil"}">>]}]}
4> Decoded = test:decode(Results).
[{[{<<"age">>,24},{<<"name">>,<<"krishna">>}]},
{[{<<"age">>,29},{<<"name">>,<<"sharat">>}]},
{[{<<"age">>,25},{<<"name">>,<<"ramesh">>}]},
{[{<<"age">>,28},{<<"name">>,<<"kumar">>}]},
{[{<<"age">>,24},{<<"name">>,<<"gopi">>}]},
{[{<<"age">>,27},{<<"name">>,<<"anil">>}]}]
5> test:get_age(<<"krishna">>, Decoded).
24
6>
如果您不局限于使用JSON,还有另一种方法:如果您的应用程序使用Erlang,请考虑在存储对象时使用proplist。如果要像
这样存储每个值[{<<"age">>,24},{<<"name">>,<<"krishna">>}]
,
从您的MR返回的结果可能看起来像这样:
{ok,[{0,
[{<<"age">>, 24}, {<<"name">>, <<"krishna">>}],
[{<<"age">>, 29}, {<<"name">>, <<"sharat">>}],
[{<<"age">>, 25}, {<<"name">>, <<"ramesh">>}]}]}
那么你可以用[ {proplists:get_value(<<"name">>,V),proplists:get_value(<<"age">>,V) || V <- R ].
返回:
[{<<"krishna">>,24},
{<<"sharat">>,29},
{<<"ramesh">>,25}]
要从特定记录中提取特定字段,可以使用:
[ "age: " ++ integer_to_list(proplists:get_value(<<"age">>,Record) ||
Record <- R, proplists:get_value(<<"name">>,Record) =:= <<"krishna">> ].
还要留意R17兼容的客户端,您可能会发现Erlang的新映射数据类型很有用