Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/search/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Search Erlang Mnesia中的分页搜索_Search_Pagination_Erlang_Mnesia - Fatal编程技术网

Search Erlang Mnesia中的分页搜索

Search Erlang Mnesia中的分页搜索,search,pagination,erlang,mnesia,Search,Pagination,Erlang,Mnesia,例如,给定的记录 -record(item, { id, time, status}). 我想搜索1000到1100个项目,按时间和状态排序=:= 有什么建议吗?我认为,您应该使用mnesia:select/2来选择status=:=的对象,然后您可以使用list:sort按时间对结果进行排序,最后您可以使用list:sublist/3将元素从1000减去1100 以下是链接: 这取决于查询的外观。如果你需要订购很多不同的栏目,那么我会考虑使用SQL而不是MNESIA.< 但是,如

例如,给定的记录

-record(item, {
  id,
  time,
  status}).
我想搜索1000到1100个项目,按时间和状态排序=:=

有什么建议吗?

我认为,您应该使用mnesia:select/2来选择status=:=的对象,然后您可以使用list:sort按时间对结果进行排序,最后您可以使用list:sublist/3将元素从1000减去1100

以下是链接:

这取决于查询的外观。如果你需要订购很多不同的栏目,那么我会考虑使用SQL而不是MNESIA.< 但是,如果您只需要所描述的查询类型,那么应该能够使用表的类型来处理排序、分页和约束

以下是一些未经测试的代码,为您提供了要点:

% time goes first because it's our primary sort key
-record(statuses, {time, id, status}).
...
create_table() ->
  mnesia:create_table(statuses, [
                        {attributes, record_info(fields, statuses)}
                       ,{type, ordered_set}
                       ]).

-spec fetch_paged(integer()) -> {[tuple()], continuation()}|'$end_of_table'.
fetch_paged(PageSize) ->
  MatchSpec = {#statuses{id = '$1', status = <<"finished">>, _ = '_'}, [], ['$1']},
  mnesia:select(statuses, [MatchSpec], PageSize, read).

-spec next_page(continuation()) -> {[tuple()], continuation()}|'$end_of_table'.
next_page(Cont) ->
  mnesia:select(Cont).

基本上,mnesia:select/4提供一页结果和下一页结果的延续。没有一种内置的方法可以像SQL DB那样跳转到第1000个结果,因此如果您需要这种能力,您可以自己构建它,并保留一个时间索引,以便您可以快速查找表中的第1000个时间是{{2015,4,12},{23,53,8},然后在运行select时将其用作保护。

您可以使用QLC游标,如下所示:

order(table_name,[id,Direction]) ->
case Direction of
    descent -> fun(A,B) -> A#table_name.id > B#table_name.id end;
    ascent -> fun(A,B) -> A#table_name.id < B#table_name.id end
end;

select(universal,[Data_module,Table,Minor,Major,Order_by,Direction,Query]) ->
try
    if
        Minor == Major -> {error};
        Minor == 0; Major == 0 -> {error};
        true ->
            case apply(Data_module,order,[Table,[Order_by,Direction]]) of
                error -> {error};
                Order ->
                    Transaction = fun() ->
                        Query = qlc:q([X||X <- mnesia:table(Table)]),
                        Handler = qlc:sort(Query,[{order,Order}]),
                        Cursor = qlc:cursor(Handler),
                        if
                            Minor == 1 ->
                                Result = qlc:next_answers(Cursor,Major),
                                qlc:delete_cursor(Cursor),
                                Result;
                            true ->
                                qlc:next_answers(Cursor,Minor-1),
                                Result = qlc:next_answers(Cursor,Major-Minor+1),
                                qlc:delete_cursor(Cursor),
                                Result
                        end
                    end,
                    mnesia:transaction(Transaction)
            end
    end
catch
    Exception:Reason -> {error}
end.
QLC的手册在这里
但这种方法并不是生产中最快的方法,因为中等重负载每秒测试的连接数不足10000个,但如果在内存可用空间内遇到更多问题,则需要将其提高到非常有用的程度。我对Mnesia的相对缺乏经验的印象是,你可以把它看作是一个NoSQL数据库,在这里你完全可以理解,你不能要求第1000页,或者你可以把它看作是一个关系数据库,但没有像Postgres这样的SQL数据库的顶层接口。所以,如果你想要记忆和那些层,你需要自己构建它们。这基本上就是BlackMamba使用fetch/sort/slice操作所做的。想象一下,将其写入一个进行少量缓存的gen_服务器。您可以使用dirty_match_object vs select/2来获得很好的加速效果。因为您可能不关心分页用例中的一致性。如果您的数据集特别大,您将耗尽RAM来执行此操作。你需要使用像dirty_u/next/2这样的东西。