2017-09-09 47 views
0

因此,我將項目存儲在ets/dets表中。目前我正在用postgres做這件事,我想看看它是否可以在沒有它的情況下完成,或者如果它顯着較慢。根據功能從ets/dets中選擇項目。無論如何,除了tab2list |> Enum.filter?

我想做一個基本的空間查詢。基本檢查一個項目在當前位置的X米範圍內。

ets = ets.new(:table, [:named_table]) 
# Data looks like this: {id, lat, lng, data} 

# This is the location of the requester, this changed on every query. 
current_location = {lat, lng} 

如果我想從請求的50M內的ets的所有項目。

ets |> :ets.tab2list |> Enum.filter(fn {_, rlat, rlng, _} = row -> 
    Haversine.distance({rlat, rlng}, current_location) < 50 
end) 

有沒有更好的方法來做到這一點?我不能像Haversine公式所使用的那樣使用警衛:math.sin/asin/sqrt。

基本上問題是。有沒有辦法通過函數查詢ETS/DETS表?或者我需要先將它提取到列表中?

回答

0

我會用:ets.foldr這裏,與功能收集符合條件的所有元素,並忽略其它:

:ets.foldr(fn {_, rlat, rlng, _}, row -> 
    if Haversine.distance({rlat, rlng}, current_location) < 50 do 
    [row | acc] 
    else 
    acc 
    end 
end, [], ets) 

這將節省您先在表構成一個列表中的所有行的開銷,:ets.tab2list會做。

(有在ets一些match*功能,但他們只接受一個match spec,並因爲它使用匹配操作在數學規範不允許你的函數不能轉換到比賽規格)

+0

。我通知還有一個是'foldr'。在我的情況下,我不關心訂單,所以我不需要'reverse',但是對於你的例子,而不是'foldl'和'reverse',你不能只用'foldr'來獲得訂單你想要它? –

+0

是的,'foldr'應該給出與'foldl' +'reverse'相同的結果。我會在答案中提及,謝謝! – Dogbert