CouchDB,版本0.10.0,使用本机erlang视图。
我有一份简单的表格文件:
{
"_id": "user-1",
"_rev": "1-9ccf63b66b62d15d75daa211c5a7fb0d",
"type": "user",
"identifiers": [
"ABC",
"DEF",
"123"
],
"username": "monkey",
"name": "Monkey Man"
}
一个基本的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});
});
}
}"
}
}
}
发出:
{"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"}}
]}
我正在研究构建一个执行相同操作的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.
发出:
{"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"]}
]}
问题是 - 如何将这些值作为元组而不是数组?我不认为我可以(或者想要)使用记录,但在元组中使用原子似乎不起作用。
lists:foreach(fun(Identifier) -> Emit(Identifier, {id, ID, username, Username, name, Name}) end, Identifiers);
失败,出现以下错误:
{"error":"json_encode","reason":"{bad_term,{<<\"user-1\">>,<<\"monkey\">>,<<\"Monkey Man\">>}}"}
思考?我知道Erlang糟透了这种特定的东西(命名访问),我可以通过约定(第一个位置的id,下一个用户名,最后的真实姓名),但这会使客户端代码非常难看。
答案 0 :(得分:13)
JSON对象{"foo":"bar","baz":1}
为{[{<<"foo">>,<<"bar">>},{<<"baz">>,1}]}
在Erlang语言中,它是一个包含在元组中的proplist。
它不漂亮,但非常有效:)
要了解它,您可以使用CouchDB附带的JSON库:
couch_util:json_decode(<<"{\"foo\":\"bar\"}">>).
//在更高版本的CouchDB中,这是ejson:decode()
答案 1 :(得分:3)
对于 test_suite_reports bd,它有 tests 字段:
[
{
"name": "basics",
"status": "success",
"duration": 21795
},
{
"name": "all_docs",
"status": "success",
"duration": 385
} ...
我写了这个来获取姓名和状态:
fun({Doc}) ->
Name = fun(L) -> proplists:get_value(<<"name">>, L, null) end,
Status = fun(L) -> proplists:get_value(<<"status">>, L, null) end,
Tests = proplists:get_value(<<"tests">>, Doc, null),
lists:foreach(fun({L}) -> Emit(Name(L), Status(L)) end, Tests)
end.
答案 2 :(得分:0)
如果您喜欢实验性功能(仍然有用......),您可能需要查看Erlang exprecs。
我发现为Erlang创建一种动态记录非常有帮助。