在Java中限制响应大小的riak mapreduce [英] riak mapreduce with limit on response size in java

查看:112
本文介绍了在Java中限制响应大小的riak mapreduce的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在Riak 1.4上运行mapReduce查询,该查询按二级索引查询,按日期对记录进行排序,然后将结果限制为第一条记录.

I'm trying to run a mapReduce query on Riak 1.4 that queries by secondary index, sorts the records by date, and then limits the results to the first record.

我已经使二级索引查询工作了.排序似乎什么也没做.排序没有错误,只返回未排序的结果.返回的记录数限制导致服务器返回"bad_json"错误.

I've got the secondary index query working. The sort doesn't seem to do anything. No errors on the sort, just returns the results unsorted. The limit on the number of records returned yields a 'bad_json' error returned by the server.

这就是我所拥有的.假设查询汽车"存储桶中"john_doe"拥有的最新汽车. (为了保护无辜者,一些名称已更改;):

Here's what I have. It is suppose to query the "cars" bucket for the most recent car owned by "john_doe". (some names have been changed to protect the innocent;) :

JSSourceFunction dateSortFunction = new JSSourceFunction(
    "function(v) {" +
        "return v.sort(function(a, b) {" +
            "return a.issueDate - b.issueDate ;" +
        "}" +
    ");" +
"}");

IndexQuery iq = new BinValueQuery(BinIndex.named("person"), "cars", "john_doe");

MapReduceResult response = session.mapReduce(iq)
   .addMapPhase(NamedErlangFunction.MAP_OBJECT_VALUE)
   .addReducePhase(dateSortFunction)
   .addReducePhase(new NamedJSFunction("Riak.reduceLimit"), 1)
   .execute();

我已经看到许多关于排序的帖子,希望最终能弄清楚.但是,我对LIMIT函数的工作方式没有任何帮助.

I've seen a number of posts on sorting and am hoping to figure it out eventually. However, I haven't seen any help on how the LIMIT function might work.

提前谢谢!

更新: 多亏了乔,他使我走上了正确的道路.这就是为我工作的最终结果.我的日期格式是ISO 8601(例如2011-05-18T17:00:00-07:00).因此,我可以按词法比较正确排序.另外,我找到了javascript的数组缩短方法,并更新了代码以返回到前5个对象.

Update: Thanks to Joe, he put me on the right track. Here's what ended up working for me. My date format is ISO 8601 (eg. 2011-05-18T17:00:00-07:00). So, I can lexically compare for the correct sorting. Also, I found javascript's array shortening method and updated the code to return up-to the first 5 objects.

JSSourceFunction sortLimitFunction = new JSSourceFunction(
    "function(v) {" +
        "v.sort(function(a, b) {" +
            "return a.issueDate < b.issueDate" +
        "}" +
    ");" +
    "if (v.length > " + "5" + ") { " +
        "v.length = " + "5" + ";" +
    "}" +
    "return v;" +
"}");

IndexQuery iq = new BinValueQuery(BinIndex.named("person"), "cars", "john_doe");

MapReduceResult response = session.mapReduce(iq)
    .addMapPhase(new NamedJSFunction("Riak.mapValuesJson"))
    .addReducePhase(sortLimitFunction)
    .execute();

推荐答案

对于排序,有一个

For the sorting, there is a mailing list post that covers this topic. The main difference I see between that implementation and yours is the use of the JavaScript Riak.mapValuesJson function in the map phase.

作为限制,如果只需要排序列表中的第一项,请尝试使您的排序函数仅返回第一个元素.由于部分结果集从各个vnode到达时,reduce函数可以(可能被调用)多次,但合并列表中的第一个元素也必须是其起源的部分列表中的第一个元素,因此,这应该为您提供您正在寻找:

For the limiting, if you want just the first item from the sorted list, try having your sort function return only the first element. While the reduce function can (and probably is) called multiple times as partial result sets arrive from the various vnodes, the first element in the consolidated list must also be the first element in the partial list where it originated, so this should give you what you are looking for:

JSSourceFunction dateSortFunction = new JSSourceFunction(
    "function(v) {" +
        "var arr = v.sort(function(a, b) {" +
            "return a.issueDate - b.issueDate ;" +
            "}" +
        ");" +
        "if (arr.length == 0) { " +
           "return [];" +
        "} else {"
           "return arr[0];" + 
        "}"
    "}"
);

这篇关于在Java中限制响应大小的riak mapreduce的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆