簡體   English   中英

Riak的Erlang PB客戶端和地圖提取

[英]Riak's erlang pb client and map fetch

我正在嘗試在Riak中存儲寄存器和集的映射,並使用Riak的pb客戶端對其進行處理。 我的目標是保存地圖,然后從返回的對象中提取持久化的地圖並進行處理(在這種情況下,從集合中提取寄存器,值並轉換為JSON)。 似乎試圖使用riakc_map:fetch從返回的對象中提取值不是正確的方法?

這是我創建它的方式(鍵是一個uuid,QP是整數列表):

M = riak:new_map(),
M1 = riak:map_update({<<"post_id">>, register},
    fun(R) -> riakc_register:set(Key, R) end, M),
M2 = riak:map_update({<<"userids">>, set},
    fun(S) ->
        [riakc_set:add_element(helpers:int_to_bin(Q), S) || Q <- QP]
    end, M2),
[...]

然后,將其包裝在一個對象中,然后保存該對象。

Obj = riakc_obj:new(<<?POST_BUCKET>>, Key, Map) %% Map created via new_map()
{ok, Obj2} = riakc_pb_socket:put(Pid, <<?POST_BUCKET>>, Obj, [return_body])

現在這是我遇到麻煩的地方:

Post = binary_to_term(riakc_obj:get_value(Obj2)));
Keys = riakc_map:fetch_keys(Post),  %% returns []
OrigMap = riakc_map:value(Post),    %% returns []
IsKey1 = riakc_map:is_key({<<"post_id">>, register}, Post), %% false
IsKey2 = riakc_map:is_key({<<"post_id">>}, Post),   %% false

最重要的是

PostId = riakc_map:fetch({<<"post_id">>, register}, Post),

死於

{function_clause, [{orddict,fetch, ...

binary_to_term(riakc_obj:get_value(Obj2)))之后發布; 據我所知,看起來是正確的:

< Post = {map,[],
          [{{<<"content">>,register},
            {register,<<>>,<<"<post>Hello, World!\r\n</post>">>}},
           {{<<"post_id">>,register},
            {register,<<>>,<<"238e4300-a651-11e4-86c8-6003088f077a">>}},
           {{<<"userids">>,set},
              [{set,[],[<<"-1">>],[],undefined}]},
            .....

非常感謝任何幫助!

有些事情不太正確。 這個電話要更新

M2 = riakc_map:update({<<"userids">>, set}, 
    fun(S) ->
        [riakc_set:add_element(helpers:int_to_bin(Q), S) || Q <- QP]
    end, M1),

不創建具有多個成員的集合,而是創建每個具有單個成員的集合的列表。 如果要構造一組整數,請使用fold而不是列表推導:

M2 = riakc_map:update({<<"userids">>, set}, 
    fun(S) ->
        lists:foldl(
               fun(Q, Acc) ->
                   riakc_set:add_element(helpers:int_to_bin(Q), Acc) 
               end, 
               S, QP),
    end, M1),

這實際上並不會更新地圖的值,而是在記錄中進行更新:

#map{value = [],
     updates = [{{<<"post_id">>,register},
                 {register,<<>>,<<"uuid">>}},
                {{<<"userids">>,set},
                 {set,[],
                      [<<"1">>,<<"10">>,<<"2">>,<<"3">>,<<"4">>,<<"5">>,<<"6">>,
                       <<"7">>,<<"8">>,<<"9">>],
                      [],undefined}}],
     removes = [],context = undefined}

此時, riakc_map:value返回[]因為這是記錄中的值。 要將分階段的更新應用於該值,您需要調用riakc_pb_socket:modify_type ,該方法還將值存儲在Riak中。


全過程

准備Riak集群以使用地圖CRDT

  • 創建存儲桶類型以保存地圖
    root@node# riak-admin bucket-type create maps '{"props":{"datatype":"map"}}'

  • 激活鏟斗類型
    root@node# riak-admin bucket-type activate maps

創建地圖並更新Riak

1> rr(riakc_map).
[map]
2> {ok,Pid}=riakc_pb_socket:start("127.0.0.1",8087),
2> M=riakc_map:new(),
2> Key = <<"testkey">>,
2> Bucket = <<"testbucket">>,
2> Type = <<"maps">>,
2> QP = lists:seq(1,10),
2> M1 = riakc_map:update({<<"post_id">>, register},
2> fun(R) -> riakc_register:set(Key, R) end, M),
2> M2 = riakc_map:update({<<"userids">>, set},
2> fun(S) ->
2> lists:foldl(fun(Q,Acc) -> riakc_set:add_element(list_to_binary(integer_to_list(Q)), Acc) end,S, QP)
2> end, M1),
2> riakc_pb_socket:modify_type(Pid,fun(_) -> M2 end,{Type,Bucket},Key,[create]).
ok

檢索地圖並檢查值

3> {ok,Map} = riakc_pb_socket:fetch_type(Pid,{Type,Bucket},Key),
3> riakc_map:value(Map).
[{{<<"post_id">>,register},<<"testkey">>},
 {{<<"userids">>,set},
  [<<"1">>,<<"10">>,<<"2">>,<<"3">>,<<"4">>,<<"5">>,<<"6">>,
   <<"7">>,<<"8">>,<<"9">>]}]
4> riakc_map:fetch_keys(Map).
[{<<"post_id">>,register},{<<"userids">>,set}]
5> riakc_map:is_key({<<"post_id">>, register}, Map).
true
6> riakc_map:is_key({<<"post_id">>}, Map).
false

為了進行比較,這是存儲之前的值:

7> M2.

#map{value = [],
     updates = [{{<<"post_id">>,register},
                 {register,<<>>,<<"testkey">>}},
                {{<<"userids">>,set},
                 {set,[],
                      [<<"1">>,<<"10">>,<<"2">>,<<"3">>,<<"4">>,<<"5">>,<<"6">>,
                       <<"7">>,<<"8">>,<<"9">>],
                      [],undefined}}],
     removes = [],context = undefined}

這是最終值:

8> Map.
#map{value = [{{<<"post_id">>,register},<<"testkey">>},
              {{<<"userids">>,set},
               [<<"1">>,<<"10">>,<<"2">>,<<"3">>,<<"4">>,<<"5">>,<<"6">>,
                <<"7">>,<<"8">>,<<"9">>]}],
     updates = [],removes = [],
     context = <<131,108,0,0,0,1,104,2,109,0,0,0,8,35,9,254,
                 249,120,246,57,114,97,8,106>>}

更改現有地圖是通過隱式提取來處理的:

2> riakc_pb_socket:modify_type(Pid,
                 fun(OldMap) ->
                    riakc_map:update({<<"userids">>, set},
                               fun(S) ->
                                   riakc_set:add_element(<<"100">>, S)
                               end, OldMap)
                 end,
                 {Type,Bucket},Key,[]).
ok
3> riakc_pb_socket:fetch_type(Pid,{Type,Bucket},Key).
{ok,{map,[{{<<"post_id">>,register},<<"testkey">>},
      {{<<"userids">>,set},
       [<<"1">>,<<"10">>,<<"100">>,<<"2">>,<<"3">>,<<"4">>,<<"5">>,
        <<"6">>,<<"7">>,<<"8">>,<<"9">>]}],
     [],[],
     <<131,108,0,0,0,1,104,2,109,0,0,0,8,35,9,254,249,120,
       246,57,114,97,...>>}}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM