从CouchDB中的Erlang视图发出元组 [英] Emit Tuples From Erlang Views In CouchDB

查看:119
本文介绍了从CouchDB中的Erlang视图发出元组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



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





$ _ $$$$$$$$$$$$ 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:


  1. 使用-i
    (交互式)标志启动CouchDB

  2. 在生成的erlang shell上键入: couch_util:json_decode(<{\foo\:\bar\}>>)。

  3. 利润

//在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:

  1. Start CouchDB with the -i (interactive) flag
  2. On the resulting erlang shell, type: couch_util:json_decode(<<"{\"foo\":\"bar\"}">>).
  3. Profit

// in later versions of CouchDB, this is ejson:decode()

这篇关于从CouchDB中的Erlang视图发出元组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆