Erlang Mnesia选择结果与read,foldl

时间:2016-12-07 01:22:00

标签: erlang mnesia

我遇到了3个用例从mnesia表返回数据的情况 1.返回表的所有值,所以我使用foldl, 2.返回1行,所以我使用read 3.根据条件返回可变数量的记录,因此我使用select。

我想使用相同的代码来管理结果,但select会返回不同的数据结构。我希望有人可以帮助我重组我的选择以返回与其他选择相同的内容。

下面是问题的示例代码和结果。问题是select不会像read和foldl那样返回表的记录名。

-module(testselect2).

-export([runtest/0]).

-record(record_a, {b, c, d}).
-record(record_b, {record_a, e}).
-record(record_c, {record_b, f, intval}).
runtest() ->
mnesia:create_schema([node()]),
mnesia:start(),
mnesia:create_table(record_c, [{attributes, record_info(fields, record_c)}]),

A1 = #record_a{b = "R1", c = "T1", d = "C1"},
B1 = #record_b{record_a = A1, e = "E1"},
C1 = #record_c{record_b = B1, f = "F1", intval = 100},    

A2 = #record_a{b = "R2", c = "T2", d = "C2"},
B2 = #record_b{record_a = A2, e = "E2"},
C2 = #record_c{record_b = B2, f = "F2", intval = 200},    

A3 = #record_a{b = "R3", c = "T3", d = "C3"},
B3 = #record_b{record_a = A3, e = "E3"},
C3 = #record_c{record_b = B3, f = "F3", intval = 300},    

{atomic, Rw} = mnesia:transaction(
              fun () ->
                mnesia:write(C1),
                mnesia:write(C2),
                mnesia:write(C3)                    
              end),


io:fwrite("Result write = ~w~n", [Rw]),   

{atomic, Rr} = mnesia:transaction(
              fun () ->
                      mnesia:read({record_c, B1})

              end),
io:fwrite("Result read = ~w~n", [Rr]),   

{atomic, Rf} =
           mnesia:transaction(fun () ->
                                      mnesia:foldl(fun (Rec, Acc) -> [Rec | Acc] end,
                                                   [],
                                                   record_c)
                              end),
io:fwrite("Result foldl = ~w~n", [Rf]),                                         

MatchHead = #record_c{record_b='$1', f='$2',  intval='$3'},
Guard = {'>', '$3', 100},
Result = {{'$1', '$2', '$3'}}, 
{atomic, Rs} = mnesia:transaction(
              fun () ->  
                  mnesia:select(record_c, [{MatchHead, [Guard], [Result]}])
              end),
io:fwrite("Result select = ~w~n", [Rs]).  

===== 结果

44> testselect2:的runTest()

结果write = ok

结果读取= [{record_c,{record_b,{record_a,[82,49],[84,49],[67,49]},[69,49]},[70,49],100} ]

结果foldl = [{record_c,{record_b,{record_a,[82,49],[84,49],[67,49]},[69,49]},[70,49],100} {record_c,{record_b,{record_a,[82,51],[84,51],[67,51]},[69,51]},[70,51],300},{record_c,{record_b {record_a,[82,50],[84,50],[67,50]},[69,50]},[70,50],200}]

结果select = [{{record_b,{record_a,[82,51],[84,51],[67,51]},[69,51]},[70,51],300},{ {record_b,{record_a,[82,50],[84,50],[67,50]},[69,50]},[70,50],200}]

确定

正如你在上面看到的那样,read和foldl记录以{record_c,{...,其中select缺少record_c,只有{{...

我一直无法找到一种方法来选择返回相同的结构,因此我的处理代码可以适用于所有3个用例。任何建议都将不胜感激。

1 个答案:

答案 0 :(得分:1)

我不是mnesia专家,但我知道当你使用ETS匹配表达式时,你可以确定结果是什么样的。您使用date | cpo | production_ms | cpo_sell_profit ======================================================= 2016-08-01 | 7146 | 75187 | 2016-08-02 | 7299 | 68925 | 2016-08-03 | 7330 | 65534 | 2016-08-04 | 7416 | 72133 | 2016-08-05 | 7563 | 71442 | 创建结果术语,这使得它们在单元组中以三元组形式出现,就像我们在输出中看到的那样。根据{{​​3}},您希望使用特殊变量Result = {{'$1', '$2', '$3'}}来返回整个匹配的对象,因此这应该取代您的'$_'行:

Result = ...