从CouchDB中的Erlang视图发出元组 [英] Emit Tuples From Erlang Views In CouchDB
问题描述
我有一个简单的表单文件:
$ _ $$$$$$$$$$$$ user,
identifier:[
ABC,
DEF,
123
],
username 猴子,
名字:猴子
}
和一个基本的JavaScript设计文档:
{
_id:_design / user,
_rev:$ 94$$$$$$$$$$$ (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 ,value:{username:monkey,name:Monkey Man}},
{id:user-1,key:DEF值:{username:monkey,name:Monkey Man}},
{id:user-1,key:123 {username:monkey,name:Monkey Man}}
]}
我正在研究构建一个Erlang视图,这样做也是一样的。到目前为止的最佳尝试是:
%%地图功能
fun({Doc}) - >
case proplists:get_value(<type>>,Doc)
undefined - >
ok;
类型 - >
标识符= proplists:get_value(<identifier>>>,Doc),
ID = proplists:get_value(<_ id>>
用户名= proplists:get_value(<username>>>,Doc),
Name = proplists:get_value(<name>>
列表:foreach(fun(Identifier) - > Emit(Identifier,[ID,Username,Name])end,Identifiers);
_ - >
ok
end
end。
其中:
{total_rows:3,offset:0,rows:[
{id:user-1,key:ABC :[猴子,猴子]},
{id:user-1,key:DEF,value },
{id:user-1,key:123,值:[猴子,猴子]}
]}
问题是 - 如何将这些值作为元组取代数组,而不是数组?我不会想象我可以(或者想要)使用记录,但在元组中使用原子似乎不起作用。 列表:foreach(fun(Identifier))> Emit(标识符,{id,ID,用户名,用户名,名称,名称})end,Identifiers);
失败,出现以下错误:
{ 错误: json_encode, 理由: {bad_term,{<< \ 用户1\>>,<< \\ \\猴子\>><< \猴子人>>}}}
想法?我知道Erlang吸引了这种特定的东西(命名访问),并且我可以通过惯例(第一个位置的id,用户名下一个,最后的真实名称)来实现,但这使得客户端代码很丑陋。 >
解决方案 JSON对象 {foo:bar,baz:1}
是 {{{<foo>>,<bar>>},{<baz> ,1}]}
在Erlang语言中,它是一个包含在元组中的proplist。
它不漂亮,但非常有效:)
要获得感觉,可以使用CouchDB附带的JSON lib:
- 使用-i
(交互式)标志启动CouchDB
- 在生成的erlang shell上键入:
couch_util:json_decode(<{\foo\:\bar\}>>)。
- 利润
//在CouchDB的更新版本中,这是 ejson: decode()
CouchDB, version 0.10.0, using native erlang views.
I have a simple document of the form:
{
"_id": "user-1",
"_rev": "1-9ccf63b66b62d15d75daa211c5a7fb0d",
"type": "user",
"identifiers": [
"ABC",
"DEF",
"123"
],
"username": "monkey",
"name": "Monkey Man"
}
And a basic javascript design document:
{
"_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});
});
}
}"
}
}
}
which emits:
{"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"}}
]}
I'm looking into building an Erlang view that does the same thing. Best attempt so far is:
%% 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.
which emits:
{"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"]}
]}
The question is - how can I get those values out as tuples, instead of as arrays? I don't imagine I can (or would want to) use records, but using atoms in a tuple doesn't seem to work.
lists:foreach(fun(Identifier) -> Emit(Identifier, {id, ID, username, Username, name, Name}) end, Identifiers);
Fails with the following error:
{"error":"json_encode","reason":"{bad_term,{<<\"user-1\">>,<<\"monkey\">>,<<\"Monkey Man\">>}}"}
Thoughts? I know that Erlang sucks for this specific kind of thing (named access) and that I can do it by convention (id at first position, username next, real name last), but that makes the client side code pretty ugly.
解决方案 The JSON object {"foo":"bar","baz":1}
is {[{<<"foo">>,<<"bar">>},{<<"baz">>,1}]}
In Erlang lingua it is a proplist wrapped in a tuple.
It's not pretty, but very efficient :)
To get a feel for it you can play with the JSON lib that ships with CouchDB:
- Start CouchDB with the -i
(interactive) flag
- On the resulting erlang shell, type:
couch_util:json_decode(<<"{\"foo\":\"bar\"}">>).
- Profit
// in later versions of CouchDB, this is ejson:decode()
这篇关于从CouchDB中的Erlang视图发出元组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!