mindreframer
EtsSelect - an ETS match spec builder from a simple query language.
I needed to store some structs/maps in ETS and wanted to use a query language that felt simple and approachable.
After looking at several alternatives, I noticed that all the wrappers around ETS match specifications were doing a bit too much for my taste. This is how EtsSelect came to life. ![]()
You can dump your maps/structs into an ETS table and select them using the following query syntax:
# "OR" query
%{or: [[:=, :field1, "value1"], [:=, :field2, "value2"]]}
# "AND" query
%{and: [[:=, :field1, "value1"], [:=, :field2, "value2"]]}
# OR query with nested AND
%{or: [[:=, :status, :new], %{and: [[:=, :status, :old], [:=, :age, 50]]}]}
That’s basically it. Check out the ExUnit tests to see if this could be useful to you.
Cheers!
Most Liked
axelson
Oooh, another match spec library! I definitely welcome alternative DSLs in the space.
Are you interested in adding more support for keys that are tuples? For example in my data_tracer library I insert data that looks roughly like:
{{1723901292213, 0, "age"}, "100"}
{{1723901292214, 0, "age"}, "101"}
{{1723901292214, 0, "name"}, "bob"}
And I want to do a query to get all the values where the third element in the tuple key is "age", i.e. something like :ets.select(:my_table, match_spec) == ["100", "101"]. From what I can tell this isn’t currently possible to query via ets_select, is that right?
I also submitted a quick PR to remove the test files from the published package: Exclude test files from published package by axelson · Pull Request #1 · maxohq/ets_select · GitHub
mindreframer
@axelson I went ahead and dropped matcha in this PR: Feat: drop `matcha` package by mindreframer · Pull Request #5 · axelson/data_tracer · GitHub
It should be 100% exact behaviour, just without all the non-trivial abstractions provided by GitHub - christhekeele/matcha: 🍵 First-class Elixir match specifications..
If you want a proper query language, this should be done separately.
Have a good Saturday!
mindreframer
@axelson Thanks for the encouragement!
While it could be possible, it would change the original goal of the package. It seems you are storing arbitrary values for debugging in data_tracer, yet my use case is selecting based on field values in maps / structs.
BTW, GitHub - axelson/data_tracer: Elixir library to facilitate debugging data flow, helps capture terms for later inspection looks awesome, gonna try it out soon. If you want to have a query language for data_tracer, please give some example queries. IF your only query type is selecting on the 3rd element of the key tuple, there is probably no need for a 3rd-party library ![]()
The spec to match all elements with “age” OR “name” would look like this:
match_spec = [
{{{:_, :_, :"$3"}, :_}, [{:orelse, {:==, :"$3", "age"}, {:==, :"$3", "name"}}], [:"$_"]}
]
So, please share some examples, maybe I could contribute a query language just for data_tracer, that would be most simple and direct approach.
mindreframer
It seems the only place where you execute a query on ETS tables is this
Exactly this query should be covered by this spec:
match_spec = [
{{{:_, :_, :"$3"}, :"$4"}, [{:==, :"$3", key}], [:"$4"]}
]
Example:
:ets.new(:my_table, [:set, :public, :named_table])
:ets.insert(:my_table, {{1723901292213, 0, "age"}, "100"})
:ets.insert(:my_table, {{1723901292214, 0, "age"}, "101"})
:ets.insert(:my_table, {{1723901292214, 0, "name"}, "bob"})
key = "age"
match_spec = [
{{{:_, :_, :"$3"}, :"$4"}, [{:==, :"$3", key}], [:"$4"]}
]
result = :ets.select(:my_table, match_spec)
#=> ["101", "100"]
So… In theory you could drop your dependency on Matcha.








