[erlang-questions] mnesia question: best way to index on combined/nested fields?

Jonathan Leivent <>
Wed Jun 5 18:31:42 CEST 2013


I would like to set up an mnesia table on a record type that contains 
two data fields, such that there are indexes on each independent field 
as well as on the tuple of both fields - actually, the tuple of both 
fields should be the key.  The table represents the results of a 
concurrent 2-D cross product calculation where the most common query is 
on individual elements, but occasionally there are queries on individual 
rows and/or columns.

Is there a way to do this without replicating fields?  For example, 
suppose the record type is:

-record(foo, {x, y}).

It seems like I would instead need to use a different record type 
augmented with redundant fields, like this:

-record(bar, {foo::#foo{}, x, y}).

where R#bar.x is always kept the same as R#bar.foo#foo.x (similarly for 
y).  Then I can create the table:

  mnesia:create_table(bar, [{index, [x, y]},...]).

so that a whole foo record is the key, while (copies of) x and y are 
indexed separately.

That's not that bad, but something I see in the mnesia doc suggests that 
this might not be the best way to handle such a case.  The particular 
doc line is in the mnesia:create_table section under the index 
attribute, and it says: "{index, Intlist}, where Intlist is a list of 
attribute names (atoms) or record fields for which Mnesia shall build 
and maintain an extra index table."  In particular the way it says both 
"attribute names (atoms)" and "record fields" separately.  Does that 
mean something like the following is possible, where the table indexes 
on nested record fields?:

-record(baz, {foo::#foo{}}).  %% no redundant fields

mnesia:create_table(baz,
	[{index, [#baz.foo#foo.x, #baz.foo#foo.y]},...]).

Or, does that "or" in that line of doc really mean "also known as" - in 
which case I guess I do need to use redundant fields...

It would really be nice to be able to do something more direct, like the 
following, where the key is explicitly defined as the tuple of fields x 
and y, so that they can also be indexed separately:

mnesia:create_table(foo, [{key, {x, y}}, {index, [x, y]}, ...]).


-- Jonathan


More information about the erlang-questions mailing list