我有一个由4个riak节点组成的集群,其中包含数据。我正在尝试执行一个简单的MapReduce作业,它只是聚合,但我试图通过提供我自己的javascript函数来实现它(以便移动到更复杂的MapReduce作业)。
我的相关Java代码段是:
IndexQuery iq = new IntRangeQuery(IntIndex.named(indexId), bucketId, 11, 40);
Function mapfunc = new JSSourceFunction(
streamToString(MapReduceDriver.class.getResourceAsStream("/map_1.js")));
Function redfunc = new JSSourceFunction(
streamToString(MapReduceDriver.class.getResourceAsStream("/reduce_1.js")));
PBMapReduceResult result = (PBMapReduceResult) riakClient.mapReduce(iq)
.addMapPhase(mapfunc)
.addReducePhase(redfunc)
.execute();
两个javascript函数在哪里:
function map_keepAttr(value, keyData, arg) {
var data = Riak.mapValuesJson(value)[0];
return [ data.Attribute_17 ];
}
function reduce_aggregate(values, arg) {
return [values.length];
}
我看到的问题如下:我的查询和地图阶段确实产生了30个值。但是减少阶段报告3而不是30(因此没有正确计数)。更奇怪的是,当我使用以下reduce函数时:
function reduce_aggregate(values, arg) {
return values.length;
}
我得到了预期的结果,即一个包含正好30个条目的json数组。
任何帮助都会拯救我,因为我似乎没有了解Riak中MapReduce的工作方式。
谢谢!
答案 0 :(得分:1)
我怀疑您看到的问题可能是由于未考虑减少阶段功能的重新减少而造成的。
虽然每个记录执行一次映射阶段函数,但是在将完整数据集作为输入时,减少阶段函数不一定执行一次,而是在映射阶段输出的部分上执行recursively,直到所有记录都已处理完毕。第一次运行reduce函数所产生的结果将包含在发送到下一次调用的数组中。
为了使用reduce函数计算项目数,您需要能够将结果与先前的reduce函数区分开来,或者确保它们具有相同的格式并且无论在何处都可以正确聚合数据来自。