MongoDB Erlang驱动程序发现限制发生在哪里?

时间:2015-02-17 23:26:47

标签: mongodb erlang cursor

我正在尝试在Erlang中集成MongoDB驱动程序。

经过一些编码后,在我看来,限制检索行数的唯一方法只能在find()动作后处理光标时发生。

到目前为止,这是我的代码:

Cursor = mongo:find(Connection, Collection, Selector),
Result = case Limit of
              infinity ->
                 mc_cursor:rest(Cursor);
              _ ->
                 mc_cursor:take(Cursor, Limit)
         end,
mc_cursor:close(Cursor)
  • 我害怕的是,当收藏将是巨大的,会发生什么?
  • 获取和装入内存不是很大吗?
  • 光标基本上如何工作?
  • 或者是否有更好的方法来限制抓取?

1 个答案:

答案 0 :(得分:1)

我认为您可以使用batch_size参数。 以下代码来自mongo.erl文件

%% @doc Return projection of selected documents starting from Nth document in batches of batchsize.
%%      0 batchsize means default batch size.
%%      Negative batch size means one batch only.
%%      Empty projection means full projection.
-spec find(pid(), collection(), selector(), projector(), skip(), batchsize()) -> cursor(). % Action
find(Connection, Coll, Selector, Projector, Skip, BatchSize) ->
    mc_action_man:read(Connection, #'query'{
        collection = Coll,
        selector = Selector,
        projector = Projector,
        skip = Skip,
        batchsize = BatchSize
    }).

===============

回应评论:

在mc_action_man.erl文件中,它仍然使用游标来保存“当前位置”。

read(Connection, Request = #'query'{collection = Collection, batchsize = BatchSize} ) ->
    {Cursor, Batch} = mc_connection_man:request(Connection, Request),
    mc_cursor:create(Connection, Collection, Cursor, BatchSize, Batch).

在mc_worker.erl中,它是实际发送到db的数据,我想你可以添加write_log(ex:lager)代码来监控查找问题的实际请求。

handle_call(Request, From, State = #state{socket = Socket, ets = Ets, conn_state = CS}) % read requests
    when is_record(Request, 'query'); is_record(Request, getmore) ->
    UpdReq = case is_record(Request, 'query') of
                 true -> Request#'query'{slaveok = CS#conn_state.read_mode =:= slave_ok};
                 false -> Request
             end,
    {ok, Id} = mc_worker_logic:make_request(Socket, CS#conn_state.database, UpdReq),
    inet:setopts(Socket, [{active, once}]),
    RespFun = fun(Response) -> gen_server:reply(From, Response) end,  % save function, which will be called on response
    true = ets:insert_new(Ets, {Id, RespFun}),
    {noreply, State};