2014-05-01 55 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];" + 
     "}" 
    "}" 
);