我正在使用python-riak客户端获取数据riak bucket我得到如下数据
<<"{\"META\": {\"campaign\": \"5IVUPHE42HP1NEYvKb7qSvpX2Cm\",
\"createdat\": 1406978070.0,
\"user_email\": \"gopikrishnajonnada@gmail.com\"},
\"mode\": 2,
\"status\": \"success\"}">>
以上数据格式将存在于每个键
所以从python-riak客户端的地图阶段我得到这样的数据:
[{'5IVUPHE42HP1NEYvKb7qSvpX2Cm': 1},
{'WL6iHLCgs492rFEFvqewzvCfFfj': 2},
{'5IVUPHE42HP1NEYvKb7qSvpX2Cm': 1},
{'5IVUPHE42HP1NEYvKb7qSvpX2Cm': 2}]
所以对于上面的数据,我必须在erlang中编写一个reduce阶段,它应该在使用python-riak客户端时提供输出,如下所示:
{'5IVUPHE42HP1NEYvKb7qSvpX2Cm': {'ab_leads': 2, 'cp_leads': 1},
'WL6iHLCgs492rFEFvqewzvCfFfj': {'ab_leads': 0, 'cp_leads': 1}}
所以从映射阶段的[{key,Value}]列表中,基于此我必须通过向结果阶段引入两个新变量来编写用于检查条件的映射阶段,就像从映射阶段列表中一样{key,Value}值为0或1然后我们必须增加或计算新变量的特定键,如ab_leads,如果它是2那么我们必须计算新变量的特定键,如cp_leads。
因此,对于列表中的特定键,如果该键为0,则必须计数,然后增加ab_leads,或者如果为2,则应增加cp_leads。
所以我一直在尝试如下,但这不是按照我的意愿给出,而且我必须抓住前面的列表结果,并且应该添加到下一个值列表中,因为riak说减少阶段将如何采取每轮20分钟的值
lists:foldl(fun({Key,Mode},Acc) -> if Mode == 0;Mode == 1 -> orddict:update_counter({Key,<<"ab_leads">>},1,Acc); true -> orddict:update_counter({Key,<<"cp_leads">>},1,Acc) end end,orddict:new(),G).
上面的结果是这样的结果
[{{<<"a">>,<<"ab_leads">>},2},{{<<"a">>,<<"cp_leads">>},1}]
所以我必须转换上面的内容,如上所述,我希望结果像
[{Key,{ab_leads:1,cp_leads:2}}]
答案 0 :(得分:1)
如果我理解正确,您就会尝试为每个广告系列获取包含“模式”为1或2的总数字键。
虽然您已经询问过reduce功能,但我相信我们必须首先拍摄地图,这就是原因:
“最重要的是要明确定义减少阶段的函数可以多次评估,后面评估的输入将包括早期评估的输出。” [{{3 }}
因此,处理此问题的最简单方法是使地图的输出看起来与reduce的输出相同。所以首先让你的地图输出看起来像这样:
[{'5IVUPHE42HP1NEYvKb7qSvpX2Cm': {'ab_leads': 1, 'cp_leads': 0}}, ...]
显然,这会使reduce阶段变得更难(欢迎map / reduce),我们将把ab_leads和cp_leads传遍整个地方,这样一个元组可能更容易处理。
[{'5IVUPHE42HP1NEYvKb7qSvpX2Cm': {1, 0}}, ...]
我们的减少现在看起来像这样:
lists:foldl(fun({Key,{Ab_leads, Cp_leads}}, Acc) ->
{Ab_leadsAcc, Cp_leadsAcc} = proplists:get_value(Key, Acc, {0, 0}),
[ {Key, {Ab_leadsAcc + Ab_leads, Cp_leadsAcc + Cp_leads}} | proplists:delete(Key, Acc)]
end,
[],
G).
请注意,元组使reduce函数更容易制作,但显然你可以保留键以便将来扩展,但确保你的reduce可以处理一个proplist。如果你愿意,你可以回到orddics,但是当订单无关紧要时,支持者会更有效率。