The 'key' to Amnesia queries?

Tags: #<Tag:0x00007f1141fbc0f8>


I am trying to get a handle on how to use Amnesia in lieu of Mnesia queries. But the documentation out there leaves a lot to be desired. I wonder if anyone can shed some light?

I have defined this table …

deftable Todo_lists, [:name, :list], type: :bag do
 @type date :: {non_neg_integer(), non_neg_integer(), non_neg_integer()}
 @type t :: %Todo_lists{name: {String.t, date}, list: [%{date: date, title: String.t}]}

and added some records:

iex(n1@> :mnesia.transaction(fn ->  
 ...(n1@> :mnesia.match_object({Todo_lists, :_, :_})
...(n1@> end)

  [{Database1.Todo_lists, {"Patricia", {2017, 2, 12}},
    [%{date: {2017, 2, 12}, title: "Market"}]},
   {Database1.Todo_lists, {"Bill", {2017, 2, 11}},
    [%{date: {2017, 2, 11}, title: "walk dog"}]},
   {Database1.Todo_lists, {"Richard", {2017, 2, 11}},
    [%{date: {2017, 2, 11}, title: "playtime"}]}]}

Now I can get some basic Amnesia queries to work:

iex(n1@> use Database1
[Amnesia, Amnesia.Fragment, Exquisite, Database1, Database1.Todo_lists,
 Database1.Todo_lists, Database1.User, Database1.User, Database1.Message,
iex(n1@> use Amnesia
iex(n1@> Amnesia.transaction do                                
...(n1@>{"Patricia", {2017, 2, 12}})          
...(n1@> end
[%Database1.Todo_lists{list: [%{date: {2017, 2, 12}, title: "Market"}],
  name: {"Patricia", {2017, 2, 12}}}]
iex(n1@> Amnesia.transaction do   
...(n1@> r = Todo_lists.where(name == {"Patricia", {2017, 2, 12}}) 
...(n1@> r |> Amnesia.Selection.values |> Enum.each(&IO.inspect(&1)) 
...(n1@> end

%Database1.Todo_lists{list: [%{date: {2017, 2, 12}, title: "Market"}],
 name: {"Patricia", {2017, 2, 12}}}

Ok, great. But now I want to do something like this but in Amnesia:

iex(n1@> :mnesia.transaction(fn ->
...(n1@> :mnesia.match_object({Todo_lists, {"Patricia", :_}, :_})
...(n1@> end)

 [{Database1.Todo_lists, {"Patricia", {2017, 2, 12}},
   [%{date: {2017, 2, 12}, title: "Market"}]}]}

In other words, how do I specify a wild card query using Amnesia?
I tried using Todo_lists.match, but I can’t even guess at the syntax.
Using help on this tells me to refer to mnesia.match, but that doesn’t really help.

I think Amnesia could be really cool if someone would just provide some basic documentation. That someone could be me if I could just figure out some basics.
(rant over :slight_smile:)



Honestly I’m not sure that I would use Amnesia. It’s basically its own syntax which wildly limits the resources available to you for help. If you use :mnesia and its regular tools then anyone who has used mnesia or any existing mnesia docs are helpful. If you use Amnesia you’re limited to other people who use Amnesia.


Yes, I had come to that same conclusion last week. And the Elixir app I am currently developing is using straight mnesia. But I have been running into other query challenges with elixir-mnesia as well –

– so I decided to give Amnesia another go. After messing around for a couple of hours, and numerous Google searches, I decided to ask the forum.

I see there is a Qlc library out there that may help. I don’t mind using Erlang list comprehensions/syntax to get what I need so I may try that route next. Ecto is not really an option for me because my app uses it’s own cache.

If you have any other suggestions I would love to hear them. I am anxious to move on.

Many thanks for your input.


I’ve been futzing around with this briefly this morning.

It appears you can interop a little bit back and forth with Amnesia but one would need to dig into library internals to insure something like the following is always kosher,

iex(43)> Amnesia.Fragment.transaction do                                                                                                          
...(43)> %Amnesia.Table.Select{coerce: AMNESIA_TABLE, continuation: nil, values:                                  
...(43)> (:mnesia.match_object({ AMNESIA_TABLE, :_, { {:ref, 2010001, REPO}, :_}, :_, :_}))
...(43)> } end |> Amnesia.Selection.values    

in the above i’m pattern matching on an object that contains the tuple {{:ref, 2010001, REPO}, :_} and wrapping the results in the structure Amnesia uses to avoid the need to manually reconstruct the struct.

If I were performing a select i’d have to catch the continuation
Amnesia.transaction do
{values, continuation} = …
%Amnesia.Table.Select{coerce: AMNESIA_TABLE, continuation: continuation, values: values}
end |> Amnesia.Selection.values

completely tangential, REPO here is a repository class in my codebase that that will return the referenced object when one calls REPO.get(2010001). So I am filtering by an entry associated with what is essentially another record in another table.

#5 appears to be a match type query.


Here you go,

The below built in match method seems to work exactly as needed for the following query against a calendar entry with a date tuple of format {year, month, week, day}

match = [date: {year, month, iso_week,  :_}]