2017-09-09 3 views
0

私はアイテムをets/detsテーブルに保存しています。現在、私はポストグルでそれをやっていますが、それがなくても、それともかなり遅くなったのかを見たいと思います。関数に基づいてets/detから項目を選択します。とにかく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.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

.Iもあります予告'foldr'。私の場合、私は順序を気にしないので、 'reverse'は必要ありませんが、あなたのexmpleでは、' foldl'と 'reverse'の代わりに' foldr'を使って順番に得ることができませんでしたあなたはそれをしたい? –

+0

'foldr'は' foldl' + 'reverse'と同じ結果を返さなければなりません。私はその答えに感謝します! – Dogbert

関連する問題