ETS table select 所有匹配id的记录

ETS table select all records matching id

嘿,我有一个 ets table transactions,table 的一部分看起来像这样。

[
  {"txn_05h0f14877a091yj7358a",
   %{
     account_id: "acc_f5f3f6y7t8s7a5htj78ty",
     amount: 289,
     date: ~D[2022-03-16],
     details: %{
       details: %{
         category: "transport",
         counterparty: %{name: "UBER", type: "organization"},
         processing_status: "complete"
       }
     },
     links: %{
       account: "http://localhost:4000/accounts/acc_f5f3f6y7t8s7a5htj78ty",
       self: "http://localhost:4000/accounts/acc_f5f3f6y7t8s7a5htj78ty/balances/transactions/txn_f5f3f6y7t8s7a5htj78ty"
     },
     running_balance: 100000,
     status: "posted",
     type: "card_payment"
   }}
]

我想 select 所有匹配的记录 account_id 我正在做这样的事情

iex(23)> fun = :ets.fun2ms(fn {_, {account_id}} when account_id == "acc_f5f3f6y7t8s7a5htj78ty" -> account_id end)
[{{:_, {:""}}, [{:==, :"", "acc_f5f3f6y7t8s7a5htj78ty"}], [:""]}]
iex(24)> :ets.select(:transactions, fun)
[]

但是查询没有正常工作。 selecting 所有匹配 account_id 的记录的正确方法是什么?

您的方法有效,但您的模式与数据的形状不匹配:它需要形状为 {"txn_05h0f14877a091yj7358a", {"acc_f5f3f6y7t8s7a5htj78ty"}}.

的记录

您需要查找地图 :account_id 键:

iex> fun = :ets.fun2ms(fn {_, transaction} when transaction.account_id == "acc_f5f3f6y7t8s7a5htj78ty" -> transaction end)
[
  {{:_, :""},
   [{:==, {:map_get, :account_id, :""}, "acc_f5f3f6y7t8s7a5htj78ty"}],
   [:""]}
]
iex> :ets.select(:transactions, fun)
[
  %{
    account_id: "acc_f5f3f6y7t8s7a5htj78ty",
    amount: 289,
    ...
  }
]

注意:when transaction.account_id == 守卫需要 Elixir >= 1.11,如果您使用的是旧版本,也可以使用 when :erlang.map_get(:account_id, transaction) ==