2014-05-01 30 views
0

我试图运行,通过二级索引的查询上了Riak 1.4 MapReduce的查询响应上的大小限制了Riak的MapReduce,按日期排序记录,然后将结果限制为第一个记录。在Java

我已经得到了二级索引的查询工作。这种排序似乎没有做任何事情。没有错误,只是返回未排序的结果。返回记录数量的限制会导致服务器返回的'bad_json'错误。

这是我的。假设查询“john_doe”拥有的最近一辆车的“cars”桶。 (有些名称已更改为保护无辜者):

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功能如何工作的帮助。

在此先感谢!

更新: 感谢乔,他让我走上了正确的轨道。这是最终为我工作的东西。我的日期格式为ISO 8601(例如2011-05-18T17:00:00-07:00)。所以,我可以在词汇上比较正确的排序。另外,我找到了JavaScript的数组缩短方法,并更新了代码以返回到前5个对象。

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(); 

回答

1

对于排序,有一个覆盖此主题的mailing list post。我在这个实现和你的实现之间的主要区别是在map阶段使用JavaScript Riak.mapValuesJson函数。

对于限制,如果你想刚刚从排序列表中的第一个项目,尝试让你的排序功能只返回第一个元素。虽然减少功能(也许是)调用多次为部分结果集,从不同的虚拟节点到达,在合并列表中的第一个元素也必须是在部分列表,它起源的第一要素,所以这应该能给你带来什么您正在寻找:

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];" + 
     "}" 
    "}" 
);