【发布时间】:2011-01-25 18:25:44
【问题描述】:
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 在第一位,用户名在后,真名在后)来做到这一点,但这使得客户端代码非常难看。
【问题讨论】:
-
我不知道 CouchDB 的详细信息,所以我不知道
Emit指的是什么函数,但显然 CouchDB 中使用的 json_encode 需要一个列表作为输入。见:svn.apache.org/viewvc/couchdb/trunk/src/couchdb/… -
Emit 是从 map 函数返回数据的函数,以便稍后减少。它在 JS 版本中有一个等价物,我认为它们都内置在 CouchDB 视图机制中。感谢您的链接。这就解释了为什么它不起作用。现在,要了解如何解决它:)
-
我知道一般的emit是什么;我只是不知道您粘贴的代码中
Emit变量引用的函数。 -
能否请您指出如何使用职位来做到这一点?