Amnesia - how to sort results?

I am using the Amnesia library from github:

I know how to query and return results using the select: clause. However, how do I sort the results by a specific column? I could sort the results myself using Elixir code but want to know if there was a way to query it so that it returned already sorted in the order I want. Similar to ORDER BY in SQL.

Below is my function - I want the results sorted by insert_ts descending (meaning latest record first):

  def read_result(task_uuid_) do
    Amnesia.transaction do
      result = SearchResult.where(
        task_uuid == task_uuid_, 
        select: [id, task_uuid, question, user, result, insert_ts])
      result
      |> Amnesia.Selection.values
    end
  end

You would add Enum.sort/2 passing in the values and how you want to sort after you Amnesia call. Amnesia is just a think wrapper around the built-in Erlang’s Mnesia, which is not SQL, it is a simple distributed KV store, so you can get and receive, but the order is dependent on the underlaying table type you chose are creation. To sort the data you just sort it as you would any normal data you got from anywhere, and Enum.sort/2 is the usual way to do it, although there are other ways of course, but that will do you most of the time. :slight_smile:

I don’t know about Amnesia but mnesia supports sorting through qlc
erlang module. Qlc is quite nifty and supports joins and sorting and
other stuff (erl -man qlc for more information)

I don’t know if it is supported in elixir though as if I remember
correctly qlc depends on erlang parse transforms. I found[1] which
claims to be a wrapper. If supported it will likely be faster than using
an Enum sort afterwards. However, if your result set is smallish it
doesn’t matter much what you use.

[1] https://github.com/k1complete/qlc

2 Likes

Thanks. I added my own sort on the 5th column as such:

 def read_results(task_uuid_) do
    Amnesia.transaction do
      result = SearchResult.where(
        task_uuid == task_uuid_, 
        select: [id, task_uuid, question, user, result, insert_ts])
      result
      |> Amnesia.Selection.values
      |> Enum.sort(fn(rec1, rec2) -> Enum.at(rec1, 5) > Enum.at(rec2, 5) end)
    end
  end
1 Like