在CouchDB中从Erlang视图中发出元组

maj*_*oat 10 erlang couchdb tuples

CouchDB,版本0.10.0,使用本机erlang视图.

我有一个简单的表格文件:

{
   "_id": "user-1",
   "_rev": "1-9ccf63b66b62d15d75daa211c5a7fb0d",
   "type": "user",
   "identifiers": [
       "ABC",
       "DEF",
       "123"
   ],
   "username": "monkey",
   "name": "Monkey Man"
}
Run Code Online (Sandbox Code Playgroud)

和一个基本的JavaScript设计文档:

{
   "_id": "_design/user",
   "_rev": "1-94bd8a0dbce5e2efd699d17acea1db0b",
   "language": "javascript",
   "views": {
     "find_by_identifier": {
       "map": "function(doc) {
          if (doc.type == 'user') {
            doc.identifiers.forEach(function(identifier) {
              emit(identifier, {\"username\":doc.username,\"name\":doc.name});
            });
          }
       }"
     }
   }
}
Run Code Online (Sandbox Code Playgroud)

发出的:

{"total_rows":3,"offset":0,"rows":[
{"id":"user-1","key":"ABC","value":{"username":"monkey","name":"Monkey Man"}},
{"id":"user-1","key":"DEF","value":{"username":"monkey","name":"Monkey Man"}},
{"id":"user-1","key":"123","value":{"username":"monkey","name":"Monkey Man"}}
]}
Run Code Online (Sandbox Code Playgroud)

我正在研究构建一个执行相同操作的Erlang视图.迄今为止的最佳尝试是:

%% Map Function
fun({Doc}) ->
    case proplists:get_value(<<"type">>, Doc) of
    undefined ->
        ok;
    Type ->
        Identifiers = proplists:get_value(<<"identifiers">>, Doc),
        ID = proplists:get_value(<<"_id">>, Doc),
        Username = proplists:get_value(<<"username">>, Doc),
        Name = proplists:get_value(<<"name">>, Doc),
        lists:foreach(fun(Identifier) -> Emit(Identifier, [ID, Username, Name]) end, Identifiers);
    _ ->
        ok
    end
end.
Run Code Online (Sandbox Code Playgroud)

发出的:

{"total_rows":3,"offset":0,"rows":[
{"id":"user-1","key":"ABC","value":["monkey","Monkey Man"]},
{"id":"user-1","key":"DEF","value":["monkey","Monkey Man"]},
{"id":"user-1","key":"123","value":["monkey","Monkey Man"]}
]}
Run Code Online (Sandbox Code Playgroud)

问题是 - 如何将这些值作为元组而不是数组?我不认为我可以(或者想要)使用记录,但在元组中使用原子似乎不起作用.

lists:foreach(fun(Identifier) -> Emit(Identifier, {id, ID, username, Username, name, Name}) end, Identifiers);
Run Code Online (Sandbox Code Playgroud)

失败,出现以下错误:

{"error":"json_encode","reason":"{bad_term,{<<\"user-1\">>,<<\"monkey\">>,<<\"Monkey Man\">>}}"}
Run Code Online (Sandbox Code Playgroud)

思考?我知道Erlang糟透了这种特定的东西(命名访问),我可以通过约定(第一个位置的id,下一个用户名,最后的真实姓名),但这使得客户端代码非常难看.

Jan*_*rdt 13

JSON对象{"foo":"bar","baz":1}{[{<<"foo">>,<<"bar">>},{<<"baz">>,1}]}

在Erlang语言中,它是一个包含在元组中的proplist.

它不漂亮,但效率很高:)

要了解它,您可以使用CouchDB附带的JSON库:

  1. 使用-i(交互式)标志启动CouchDB
  2. 在生成的erlang shell上,键入: couch_util:json_decode(<<"{\"foo\":\"bar\"}">>).
  3. 利润

//在CouchDB的更高版本中,这是 ejson:decode()