CouchDB, versión 0.10.0, utilizando vistas de erlang nativas.Emitir Tuplas desde vistas de Erlang en CouchDB
Tengo un documento simple de la forma:
{
"_id": "user-1",
"_rev": "1-9ccf63b66b62d15d75daa211c5a7fb0d",
"type": "user",
"identifiers": [
"ABC",
"DEF",
"123"
],
"username": "monkey",
"name": "Monkey Man"
}
Y un documento de diseño Javascript básica:
{
"_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});
});
}
}"
}
}
}
que emite:
{"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"}}
]}
Estoy buscando en la construcción una vista de Erlang que hace lo mismo. Mejor intento hasta ahora es:
%% 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.
que emite:
{"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"]}
]}
La pregunta es - ¿Cómo puedo conseguir esos valores como tuplas, en lugar de como matrices? No me imagino que puedo (o me gustaría) usar registros, pero el uso de átomos en una tupla no parece funcionar.
lists:foreach(fun(Identifier) -> Emit(Identifier, {id, ID, username, Username, name, Name}) end, Identifiers);
se produce el siguiente error:
{"error":"json_encode","reason":"{bad_term,{<<\"user-1\">>,<<\"monkey\">>,<<\"Monkey Man\">>}}"}
Pensamientos? Sé que Erlang apesta por este tipo específico de cosas (acceso con nombre) y que puedo hacerlo por convención (identificación en primera posición, nombre de usuario siguiente, nombre real en último lugar), pero eso hace que el código del lado del cliente sea bastante feo.
No conozco los detalles de CouchDB, así que no tengo idea de a qué función se refiere 'Emit', pero al parecer json_encode utilizado en CouchDB requiere una lista como entrada. Ver: http://svn.apache.org/viewvc/couchdb/trunk/src/couchdb/couch_util.erl?view=markup#l317 – Zed
Emitir es la función que devuelve datos de la función de mapa para ser reducida más tarde. . Tiene un equivalente en la versión JS, y supongo que ambos están integrados en el mecanismo de vista CouchDB. Gracias por el enlace. Eso explica por qué no funciona. Ahora, para saber cómo solucionarlo :) – majelbstoat
Sé lo que se emite en general; Simplemente no conozco la función referida por la variable 'Emit' en su código pegado. – Zed