根据功能从ets / dets中选择项目。无论如何要做除了tab2list |> Enum.filter?

时间:2017-09-09 14:44:51

标签: erlang elixir

所以我将项目存储在ets / dets表中。目前我正在使用postgres,我想看看它是否可以在没有它的情况下完成,或者它是否显着变慢。

我想做一个基本的空间查询。基本上检查项目是否在当前位置的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表?或者我是否需要先将其提取到列表中?

1 个答案:

答案 0 :(得分: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将会这样做。

match*中有一些ets个函数,但它们只接受match spec并且您的函数无法转换为匹配规范,因为它使用数学规范中不允许的匹配操作。)