我有一个定义用于elixir项目的mnesia表。
iex 1> :mnesia.create_table(:todo_lists, [attributes: [:name, :list], disc_only_copies: nodes])
iex 4> :mnesia.transaction(fn ->
... 4> :mnesia.match_object({:todo_lists, :_, :_})
... 4> end)
{:atomic,
[{:todo_lists, {"normans_list", {2017, 2, 11}},
[%{date: {2017, 2, 11}, title: "job interview"},
%{date: {2017, 2, 11}, title: "market"}]},
{:todo_lists, {"obamas_list", {2017, 2, 11}},
[%{date: {2017, 2, 11}, title: "vacation"},
%{date: {2017, 2, 11}, title: "coding session"}]},
{:todo_lists, {"alices_list", {2017, 2, 14}},
[%{date: {2017, 2, 14}, title: "yoga class"}]},
{:todo_lists, {"bills_list", {2017, 2, 11}},
[%{date: {2017, 2, 11}, title: "business meeting"}]},
{:todo_lists, {"bills_list", {2017, 2, 14}},
[%{date: {2017, 2, 14}, title: "band practice"}]}]}
从上面的清单中可以看出,表元素由两元组键和一组映射组成。
像这样的匹配查询工作正常:
iex 13> :mnesia.transaction(fn ->
... 13> :mnesia.match_object({:todo_lists, {"bills_list", :_}, :_})
... 13> end)
{:atomic,
[{:todo_lists, {"bills_list", {2017, 2, 11}},
[%{date: {2017, 2, 11}, title: "business meeting"}]},
{:todo_lists, {"bills_list", {2017, 2, 14}},
[%{date: {2017, 2, 14}, title: "band practice"}]}]}
但是当我尝试这样的事情时,我看到了badarg错误:
iex 14> :mnesia.transaction(fn ->
... 14> :mnesia.select(:todo_lists, [{{:todo_lists, :"$1", :"$2"},[{:==, :"$1", {"bills_list", {2017, 2, 14}}}], [:"$$"]}])
... 14> end)
{:aborted,
{:badarg,
[:todo_lists,
[{{:todo_lists, :"$1", :"$2"}, [{:==, :"$1", {"bills_list", {2017,2,14}}}], [:"$$"]}]]}}
似乎对guard子句中的元组键的引用会导致badarg - 例如,我可以使用荒谬的[{:>,:“$ 1”,0}]来获得结果,但是我只是没有看到这里有什么问题。
我想使用:mnesia.select/2来实现这个简单的查询,这样我就可以构建它并开发一些更复杂的查询。非常感谢任何帮助。
答案 0 :(得分:1)
我对mnesia只有粗略的经验,但看起来MatchHead应该是一个结构/记录(而不是一个命名表的原子,如你的例子)。请参阅mnesia getting started文档中的“使用Mnesia函数”。
所以你的选择应该看起来像:
:mnesia.select(:todo_lists, [{%YourStructHere{ ..WhateverMatch..}, Guard, Result}])
解释{:badarg, [:todo_lists, [{{:todo_lists, :"$1", :"$2"} ...
错误,第二次出现:todo_lists。