2017-06-18 61 views
0

我在Aerospike中有一個帶有過濾器和地圖的udf流。如何:在沒有地圖的情況下寫入aerospike udf過濾器或在地圖中返回完整記錄

如果我映射,按照我所看到的所有的例子,我可以選擇從記錄的字段,並返回與過濾和選擇的領域一個新的地圖。但是,我不想這樣做。我想採取任何流,任何列/箱,應用過濾器,並返回完整的記錄。一種方法可能是使用stream:fiter(my_filter)而不使用地圖。直覺地(至少對我來說)這只是過濾和中繼流。這似乎並不奏效,令我感到沮喪。接下來我嘗試的是使用地圖,但只是傳遞完整的記錄。這也不管用。在這兩種情況下,當我說它不起作用時,我得到一個空列表作爲我的結果。

有人可以善意解釋這應該如何工作。這讓我絕對瘋了。 鑑於這是世界上最基本的事情之一,我想用udfs做,我意識到我錯過了一些明顯的東西。我應該指出,我用udf做了很多更復雜的事情,但由於某種原因,這對我來說是一個問題。

回答

2

你缺少的東西是你不能在UDF返回值中返回記錄或流類型。我相信所有的返回類型都是由aerospike系統lua模塊映射到客戶特定類型的;它不能映射回記錄「類型」。

如果你絕對要得到記錄,將密鑰存儲在一個垃圾桶,在地圖類型或字符串類型或整數類型返回斌 - 無論是最合適的類型,以您的應用程序。您也可以從地圖類型的記錄元數據中返回記錄摘要。我沒有測試通過UDF檢索和返回記錄摘要,但值得一試。

一旦你有命名空間,和你的密鑰,或命名空間&記錄摘要,您可以從客戶端API訪問記錄。記錄摘要是從集名和密鑰的組合中計算出來的RIPEMD160哈希值。

+0

感謝pgupta爲您的迴應。是的,我知道我可以返回密鑰和摘要,並且通過閱讀各種文檔和白皮書,我明白記錄摘要是RIPEMD160等。我真正關心的是效率問題。我想在一次傳遞中返回所有數據,因此讓數據在那裏顯得很奇怪,返回鍵並返回數據?我也可以將選擇的列(我想要的全部或其他)傳遞給UDF並迭代地構建地圖,但這又似乎效率低下。或者,我還沒有試過這個,但是這個記錄似乎有bin名字... – ismisesisko

+0

剛剛從記錄流中返回一組過濾記錄的用例是什麼,也就是說,您希望所有數據都發送到一個客戶端節點並在客戶端節點做一些計算? Aerospike提供1)記錄udfs以修改服務器上的記錄或2)以只讀模式對一組記錄進行操作的udfs,並允許您在這些記錄中彙總信息。因此使用流udfs,您可以使用羣集上的每個節點獲取map-reduce類型的計算能力,以對其記錄集進行計算,並在客戶機節點中進行最終減少。 – pgupta

0

我想我錯過了一些東西。 我已經使用記錄udfs更新記錄和流udfs做查詢/地圖減少。問題是,地圖不是似乎允許我選擇所有列I.E.轉達他們沒有檢查他們。與同等的sql系統比較(我知道做比較並不總是合理的);我想使用沒有真映射的udfs的過濾器部分。爲什麼?因爲我沒有其他方式來選擇和過濾沒有二級索引的集合,我想要多個過濾器。我該怎麼做呢?

+0

您可以通過將參數傳遞給流udf並根據這些參數進行過濾來執行多個過濾器 - 請參閱多個過濾器:https://discuss.aerospike.com/t/record-manipulation-with-more-than-one-filter -lua/3637 - 然後返回值,您可以返回到地圖中的所有存儲區或將摘要記錄回客戶端。 – pgupta

+0

再次感謝,是的,我已經看到了這一點,我已經使用了多個過濾器。我想在一天結束時的簡短回答是不能以我想要的方式完成。我會做的只是遍歷所有的垃圾箱,並建立地圖。這不是什麼大不了的事情,只是認爲會有一種更清晰的方式。感謝您的所有意見和建議。 – ismisesisko

+0

這是因爲Aerospike中的記錄類似於RDBMS中的行(Aerospike是一個面向行的數據庫),但它不完全相同。記錄是元組(密鑰,元數據,分箱)。 RDBMS中的行只是_bins_,這是一個映射,其中鍵的名稱是列名,鍵的值是特定行的列值。因此,您需要將記錄中的所有bin名稱 - 值對轉換爲映射並從您的流UDF中返回。 –

0

在塞式記錄是元組(元數據)。一個Aerospike UDF written in Lua,不管它是一個record UDFstream UDF,只能返回所支持的類型之一 - 字符串,整數,雙,單,地圖,字節(見:Known Limitations)。

在流UDF,如果你只有你還需要記錄的濱名/ bin中值對轉換爲地圖,並返回一個過濾器:

local function bins_match_filter(bin1, bin2) 
    return function(rec) 
    if rec[bin1] and rec[bin2] and 
     (type(rec[bin1]) == type(rec[bin2])) and 
     rec[bin1] == rec[bin2] then 
     return true 
    end 
    return false 
    end 
end 

local function record_to_map(rec) 
    local ret = map() 
    for i, bin_name in ipairs(record.bin_names(rec)) do 
    ret[bin_name] = rec[bin_name] 
    end 
    return ret 
end 

function check_bins_match(stream, bin1, bin2) 
    return stream : filter(bins_match_filter(bin1, bin2)) : map(record_to_map) 
end 

您可能能夠將某些基於UDF的流式濾鏡轉換爲predicate filter表達式。它不適用於上面的例子,因爲沒有辦法比較兩個bin的值。但是對於大多數情況,謂詞表達式操作是足夠的(請參閱Java客戶端的PredExp類)。您根本不需要調用UDF,這會運行速度更快,擴展性更好,而且您不需要將記錄轉換爲bin名稱/值對映射。

相關問題