如果将“更新时间”存储为整数而不是NaiveDateTime
结构,则可以使用匹配规范。
例如,要获取当前时间作为自 Unix 纪元以来的秒数:
> DateTime.to_unix(DateTime.utc_now())
1545215338
你可以这样做:
iex(3)> :ets.new(:foo, [:public, :named_table])
:foo
iex(4)> :ets.insert(:foo, {:key1, DateTime.to_unix(DateTime.utc_now())})
true
iex(5)> :ets.insert(:foo, {:key2, DateTime.to_unix(DateTime.utc_now())})
true
iex(6)> :ets.tab2list(:foo)
[key2: 1545215144, key1: 1545215140]
iex(7)> :ets.select_delete(:foo, [{{:_, :"$1"}, [{:<, :"$1", 1545215144}], [true]}])
1
iex(8)> :ets.tab2list(:foo)
[key2: 1545215144]
在对 的调用中ets:select_delete/2
,我传递了一个匹配规范。它由三部分组成:
- 使用
{:_, :"$1"}
,我对表中的记录执行匹配。在这个例子中,我有一个包含两个元素的元组。我忽略带有 的键:_
,并将时间戳分配给带有 的匹配变量:"$1"
。
- 使用
[{:<, :"$1", 1545215144}]
,我指定我只想匹配在此时间之前带有时间戳的记录。在您的情况下,您将计算过去十秒的时间并将该值放在这里。
- 使用
[true]
,我指定要返回true
匹配的记录,在这种情况下select_delete
表示“删除此记录”。
所以调用后select_delete
,表中只剩下第二条记录。
如果时间戳在地图内,您可以使用map_get
它来访问它并进行比较:
:ets.select_delete(:foo, [{{:_, :"$1"},
[{:<, {:map_get, :updated_at, :"$1"}, 1545215339}],
[true]}])
或者(在 Erlang/OTP 18.0 及更高版本中)匹配映射值:
:ets.select_delete(:foo, [{{:_, #{updated_at: :"$1"}},
[{:<, :"$1", 1545215339}],
[true]}])