【问题标题】:How to make a counted value inside FoldRows() function available outside the function in a CouchDB list?如何使 FoldRows() 函数中的计数值在 CouchDB 列表中的函数之外可用?
【发布时间】:2014-09-23 01:43:40
【问题描述】:

我有一个用 Erlang 编写的 CouchDB 列表,如下面的代码所示。此列表将输出每一行的计数。我需要的是在遍历所有行后“发送”计数。 (仅获取最终计数)。

我怎样才能完成这项工作?尝试使用 ets 但无法成功。

    fun(Head, {Req}) ->
      Fun = fun({Row}, Acc) ->
        TheType = proplists:get_value(<<"type">>, element(1,proplists:get_value(<<"value">>,Row))),

        case TheType of
          <<"TYPEONE">> ->
            Count = Acc+1;
          _ ->
            Count = Acc
        end,

        Send(list_to_binary(io_lib:format("Count: ~p~n", [Count]))),
        {ok, Count}
      end,
      FoldRows(Fun, 0),
      ""
    end.

【问题讨论】:

    标签: erlang couchdb


    【解决方案1】:

    以下功能对我有用:-

       fun(Head, {Req}) ->      
             Fun = fun({Row}, Acc) -> 
    
                      {Val} = couch_util:get_value(<<"value">>, Row, rest),
                      TheType = proplists:get_value(<<"TheType">>, Val),
                      case TheType of
                      <<"TYPEONE">> ->
                          {ok,Acc+1};
                      _->
                          {ok,Acc}
                      end
    
    
                  end,  
        {ok, Count} = FoldRows(Fun, 0),  
        Send(list_to_binary(integer_to_list(Count))) 
    end.
    

    它检查TheType 是否属于>,如果是,则返回递增的Acc。处理完所有行后,最终结果为Send。由于您没有提供任何文件,我认为这些文件的结构如下:-

    {  
      "_id": "1fa48be41889b04936c0bf0b570002a2",   
     "_rev": "1-29eb2f161688277924b6a4a4e7ad7a78",   
     "TheType": "TYPEONE" 
    }
    

    列表的视图功能是这样的:-

    fun({Doc}) ->
      K = proplists:get_value(<<"TheType">>, Doc, null),
      Emit(K, {Doc})
    end.
    

    【讨论】:

    • 非常感谢阿克沙特。这是我的问题的确切解决方案。
    【解决方案2】:

    正如它所写,这段代码无法编译。所以我猜测一些观点并尝试回答。但通常在这个论坛中,您应该注意提出明确的问题,尽可能少地提出开放点:

    • Head 和 Req 未使用?
    • Send 和 FoldRows 是未定义的变量
    • 行的格式未定义...

    不过我可以给你一些线索

    定义一个过滤函数,如果该行符合您的条件,则返回 1,否则返回 0:

    Filter = fun({Row},Type) ->
               case proplists:get_value(<<"type">>, element(1,proplists:get_value(<<"value">>,Row))) of
                   Type -> 1;
                   _ -> 0
               end
             end,
    

    那么您需要一个包含所有行的列表,这在您的代码示例中缺失,假设 RowList 是一个包含 {Row} 形式的元素的列表。

    现在您可以使用列表库来创建计数函数:

    Count = fun(RowList,Type) -> lists:foldl(fun(X,Acc) -> Filter(X,Type) + Acc end, 0, RowList) end,
    

    并像这样使用它Count(RowList,&lt;&lt;"TYPEONE"&gt;&gt;)

    如图所示:

    27> E1 = {[{foo,0},{<<"value">>,{[{bar,0},{<<"type">>,<<"TYPEONE">>}],baz}}]}.
    {[{foo,0},
      {<<"value">>,{[{bar,0},{<<"type">>,<<"TYPEONE">>}],baz}}]}
    28> E2 = {[{foo,0},{<<"value">>,{[{bar,0},{<<"type">>,<<"TYPETWO">>}],baz}}]}.
    {[{foo,0},
      {<<"value">>,{[{bar,0},{<<"type">>,<<"TYPETWO">>}],baz}}]}
    29> E3 = {[{foo,0},{<<"value">>,{[{bar,0},{<<"notype">>,<<"TYPEONE">>}],baz}}]}.
    {[{foo,0},
      {<<"value">>,{[{bar,0},{<<"notype">>,<<"TYPEONE">>}],baz}}]}
    30> E4 = {[{foo,0},{<<"value">>,{[{bar,0},{<<"type">>,<<"TYPEONE">>}],baz}}]}.  
    {[{foo,0},
      {<<"value">>,{[{bar,0},{<<"type">>,<<"TYPEONE">>}],baz}}]}
    31> RowList = [E1,E2,E3,E4].
    [{[{foo,0},
       {<<"value">>,{[{bar,0},{<<"type">>,<<"TYPEONE">>}],baz}}]},
     {[{foo,0},
       {<<"value">>,{[{bar,0},{<<"type">>,<<"TYPETWO">>}],baz}}]},
     {[{foo,0},
       {<<"value">>,{[{bar,0},{<<"notype">>,<<"TYPEONE">>}],baz}}]},
     {[{foo,0},
       {<<"value">>,{[{bar,0},{<<"type">>,<<"TYPEONE">>}],baz}}]}]
    32> Count(RowList,<<"TYPEONE">>).
    2
    33> Count(RowList,<<"TYPETWO">>).
    1
    34>
    

    【讨论】:

    • Pascal,我给的代码确实不能直接在Erlang shell中运行。但正如我在问题中提到的,这是 CouchDB 中的“列表”功能。因此,当在 CouchDB 中用作列表时,它将正常运行。无论如何,非常感谢您的回答。你以一种很好理解的方式给出了它..
    猜你喜欢
    • 2015-02-02
    • 2023-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-20
    • 1970-01-01
    • 1970-01-01
    • 2021-12-26
    相关资源
    最近更新 更多