从 mnesia 数据库中提取特定元素

Extracting particular element from mnesia db

我们在 ejabberd 中有一个 table offline_msg.following 是存储在此 table

中的其中一条消息的快照
{offline_msg,
{<<"+1">>,<<"devlab">>}, 
{1440,484625,227224},
never,
{jid,<<"+111">>,<<"devlab">>,<<"xyz">>,<<"+111">>,<<"devlab">>,<<"xyz">>},
{jid,<<"+1">>,<<"devlab">>,<<>>,<<"+1">>,<<"devlab">>,<<>>},
{xmlel,<<"message">>,
[{<<"to">>,<<"multicast.devlab">>},
{<<"type">>,<<"group">>},
{<<"id">>,<<"**99897**">>}],
[{xmlel,<<"addresses">>,
[{<<"xmlns">>,<<"http://jabber.org/protocol/address">>}],
[{xmlel,<<"address">>,
[{<<"type">>,<<"to">>},
{<<"jid">>,<<"+1@devlab">>},  
{<<"desc">>,<<"2001,104">>}],
[]},
{xmlel,<<"address">>,
[{<<"type">>,<<"to">>},
{<<"jid">>,<<"+1@devlab">>},
{<<"desc">>,<<"2001,104">>}],
[]}]},
{xmlel,<<"subject">>,[],[{xmlcdata,<<"1440484625:GROUP">>}]},
{xmlel,<<"body">>,[],
[{xmlcdata,
<<"mod_archive,0,https://IP/downloadfiles/avatar/104.jpg">>}]},
{xmlel,<<"request">>,[{<<"xmlns">>,<<"urn:xmpp:receipts">>}],[]}]}}.

现在我的问题是->我想创建一个搜索函数,我将向其传递一个 ID,该函数将查找传递的 ID(99897) 是否存在于 table 或 not.Any 指针中?

您可以使用 Mnesia 的 match_object/3 function(或者它的等价物)在 table.

中找到匹配的对象

或者,您可以使用 the qlc module 查询 Mnesia table。

match_object/2 将起作用(您也可以使用 select/2 在单个操作中执行搜索和某些字段的提取)下面的代码完成这项工作(使用 ets 进行快速测试的示例但应该与 mnesia 一起工作):

-module (test3).

-compile([export_all]).

-include_lib("stdlib/include/ms_transform.hrl").

init() ->
    ets:new(test,[named_table,bag]),
    ets:insert(test,{offline_msg,{<<"+1">>,<<"devlab">>},{1440,484625,227224},never,
            {jid,<<"+111">>,<<"devlab">>,<<"xyz">>,<<"+111">>,<<"devlab">>,<<"xyz">>},
            {jid,<<"+1">>,<<"devlab">>,<<>>,<<"+1">>,<<"devlab">>,<<>>},{xmlel,<<"message">>,
            [{<<"to">>,<<"multicast.devlab">>},{<<"type">>,<<"group">>},{<<"id">>,<<"99897">>}],
            [{xmlel,<<"addresses">>,[{<<"xmlns">>,<<"http://jabber.org/protocol/address">>}],
                [{xmlel,<<"address">>,[{<<"type">>,<<"to">>},{<<"jid">>,<<"+1@devlab">>},{<<"desc">>,<<"2001,104">>}],[]},
                {xmlel,<<"address">>,[{<<"type">>,<<"to">>},{<<"jid">>,<<"+1@devlab">>},{<<"desc">>,<<"2001,104">>}],[]}]},
                {xmlel,<<"subject">>,[],[{xmlcdata,<<"1440484625:GROUP">>}]},{xmlel,<<"body">>,[],
                [{xmlcdata,<<"mod_archive,0,https://IP/downloadfiles/avatar/104.jpg">>}]},
                {xmlel,<<"request">>,[{<<"xmlns">>,<<"urn:xmpp:receipts">>}],[]}]}}),
    ets:insert(test,{offline_msg,{<<"+1">>,<<"devlab">>},{1440,484625,227224},never,
        {jid,<<"+111">>,<<"devlab">>,<<"xyz">>,<<"+111">>,<<"devlab">>,<<"xyz">>},
        {jid,<<"+1">>,<<"devlab">>,<<>>,<<"+1">>,<<"devlab">>,<<>>},{xmlel,<<"message">>,
        [{<<"to">>,<<"multicast.devlab">>},{<<"type">>,<<"group">>},{<<"id">>,<<"99898">>}],
        [{xmlel,<<"addresses">>,[{<<"xmlns">>,<<"http://jabber.org/protocol/address">>}],
            [{xmlel,<<"address">>,[{<<"type">>,<<"to">>},{<<"jid">>,<<"+1@devlab">>},{<<"desc">>,<<"2001,104">>}],[]},
            {xmlel,<<"address">>,[{<<"type">>,<<"to">>},{<<"jid">>,<<"+1@devlab">>},{<<"desc">>,<<"2001,104">>}],[]}]},
            {xmlel,<<"subject">>,[],[{xmlcdata,<<"1440484625:GROUP">>}]},{xmlel,<<"body">>,[],
            [{xmlcdata,<<"mod_archive,0,https://IP/downloadfiles/avatar/104.jpg">>}]},
            {xmlel,<<"request">>,[{<<"xmlns">>,<<"urn:xmpp:receipts">>}],[]}]}}),
    ets:insert(test,{offline_msg,{<<"+1">>,<<"devlab">>},{1440,484625,227224},never,
            {jid,<<"+111">>,<<"devlab">>,<<"xyz">>,<<"+111">>,<<"devlab">>,<<"xyz">>},
            {jid,<<"+1">>,<<"devlab">>,<<>>,<<"+1">>,<<"devlab">>,<<>>},{xmlel,<<"message">>,
            [{<<"to">>,<<"multicast.devlab">>},{<<"type">>,<<"group">>},{<<"id">>,<<"99897">>}],
            [{xmlel,<<"addresses">>,[{<<"xmlns">>,<<"http://jabber.org/protocol/address">>}],
                [{xmlel,<<"address">>,[{<<"type">>,<<"to">>},{<<"jid">>,<<"+1@devlab">>},{<<"desc">>,<<"2001,104">>}],[]},
                {xmlel,<<"address">>,[{<<"type">>,<<"to">>},{<<"jid">>,<<"+1@devlab">>},{<<"desc">>,<<"2001,104">>}],[]}]},
                {xmlel,<<"subject">>,[],[{xmlcdata,<<"1440484625:GROUP">>}]},{xmlel,<<"body">>,[],
                [{xmlcdata,<<"mod_archive,0,https://IP/downloadfiles/avatar/105.jpg">>}]},
                {xmlel,<<"request">>,[{<<"xmlns">>,<<"urn:xmpp:receipts">>}],[]}]}}).

test(Id) ->
    MS = {'_','_','_','_','_','_',{'_','_',['_','_',{<<"id">>,Id}],'_'}},
    ets:match_object(test,MS).

但如您所见,它取决于记录的结构,尤其是 key/value 列表 [{<<"to">>,<<"multicast.devlab">>},{<<"type">>,<<"group">>},{<<"id">>,<<"99897">>}] 的顺序。如果你绝对确信这个 lis 中的顺序永远不会改变,那很好。如果您知道大小永远不会改变,那么您可以使用匹配规范列表,例如:

test(Id) ->
    MS = [{{'_','_','_','_','_','_',{'_','_',['_','_',{<<"id">>,Id}],'_'}},[],['$_']},
          {{'_','_','_','_','_','_',{'_','_',['_',{<<"id">>,Id},'_'],'_'}},[],['$_']},
          {{'_','_','_','_','_','_',{'_','_',[{<<"id">>,Id},'_','_'],'_'}},[],['$_']}],
    ets:select(test,MS).

但我建议您将数据存储在 ets 中,记住您必须进行的不同搜索,并将数据拆分到更基本和更合理的字段中:在存储数据之前,您拥有 erlang 的所有功能和速度执行分析,而在 matchspec 中,您的功能集非常少,复杂匹配的速度相对较差。