2010-03-10 18 views
10

CouchDB, phiên bản 0.10.0, sử dụng chế độ xem bản gốc.Phát ra các bộ dữ liệu từ các lần xem Erlang Trong CouchDB

Tôi có một tài liệu đơn giản có dạng:

{ 
    "_id": "user-1", 
    "_rev": "1-9ccf63b66b62d15d75daa211c5a7fb0d", 
    "type": "user", 
    "identifiers": [ 
     "ABC", 
     "DEF", 
     "123" 
    ], 
    "username": "monkey", 
    "name": "Monkey Man" 
} 

Và một tài liệu thiết kế javascript cơ bản:

{ 
    "_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}); 
      }); 
      } 
     }" 
    } 
    } 
} 

mà phát ra:

{"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"}} 
]} 

Tôi đang tìm vào tòa nhà một cái nhìn Erlang làm điều tương tự. nỗ lực tốt nhất cho đến nay là:

%% 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. 

mà phát ra:

{"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"]} 
]} 

Câu hỏi đặt ra là - làm thế nào tôi có thể nhận được những giá trị hiện như tuples, thay vì như mảng? Tôi không tưởng tượng tôi có thể (hoặc muốn) sử dụng hồ sơ, nhưng việc sử dụng các nguyên tử trong một tuple dường như không hoạt động.

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

Không với các lỗi sau:

{"error":"json_encode","reason":"{bad_term,{<<\"user-1\">>,<<\"monkey\">>,<<\"Monkey Man\">>}}"} 

Suy nghĩ? Tôi biết rằng Erlang hút cho loại cụ thể này (có tên truy cập) và tôi có thể làm điều đó theo quy ước (id ở vị trí đầu tiên, tên người dùng tiếp theo, tên thật cuối cùng), nhưng điều đó làm cho mã phía máy khách khá xấu xí.

+0

Tôi không biết chi tiết CouchDB, vì vậy tôi không biết chức năng 'Emit' là gì, nhưng rõ ràng json_encode được sử dụng trong CouchDB yêu cầu một danh sách làm đầu vào. Xem: http://svn.apache.org/viewvc/couchdb/trunk/src/couchdb/couch_util.erl?view=markup#l317 – Zed

+0

Phát ra là hàm trả về dữ liệu từ hàm bản đồ sẽ được giảm sau này . Nó có một tương đương trong phiên bản JS, và tôi đoán chúng đều được xây dựng trong cơ chế xem CouchDB. Cảm ơn bạn đã liên kết. Điều đó giải thích tại sao nó không hoạt động. Bây giờ, để tìm hiểu làm thế nào để làm việc xung quanh nó :) – majelbstoat

+0

Tôi biết những gì phát ra là nói chung; Tôi chỉ không biết hàm được tham chiếu bởi biến 'Emit' trong mã được dán của bạn. – Zed

Trả lời

13

Các JSON đối tượng {"foo":"bar","baz":1}{[{<<"foo">>,<<"bar">>},{<<"baz">>,1}]}

Trong Erlang Lingua nó là một proplist bọc trong một tuple.

Nó không đẹp, nhưng rất hiệu quả :)

Để có được một cảm giác về nó, bạn có thể chơi với các lib JSON mà tàu với CouchDB:

  1. Bắt đầu CouchDB với -i (tương tác) cờ
  2. Trên kết quả vỏ erlang, gõ: couch_util:json_decode(<<"{\"foo\":\"bar\"}">>).
  3. Lợi nhuận

// trong các phiên bản sau này của CouchDB, đây là ejson:decode()

+0

Hoàn hảo! Điều này thực sự giúp :) – majelbstoat

+0

Khi giải mã json có khóa lồng nhau, có cần phải thoát khỏi {with a \ {không? –

0

Nếu bạn thích tính năng thử nghiệm (vẫn hoạt động ...), bạn có thể muốn xem Erlang exprecs.

Tôi thấy cực kỳ hữu ích khi tạo một loại bản ghi động cho Erlang.

3

Đối test_suite_reports bd, có kiểm tra lĩnh vực:

[ 
    { 
     "name": "basics", 
     "status": "success", 
     "duration": 21795 
    }, 
    { 
     "name": "all_docs", 
     "status": "success", 
     "duration": 385 
    } ... 

Tôi đã viết điều này để có được tên và trạng thái:

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. 
Các vấn đề liên quan