example - La mejor forma de hacer uno-a-muchos "UNIRSE" en CouchDB
pouchdb batch_size (1)
¡Gracias! ¡Este es un gran ejemplo para mostrar las nuevas características de CouchDB 0.11 !
Debe usar la función de datos relacionados con la recuperación para hacer referencia a documentos en la vista. Opcionalmente, para una JSON más conveniente, use una función _list
para limpiar los resultados. Vea el escrito de Couchio en "JOIN" s para más detalles.
Este es el plan:
En primer lugar, tiene una ventaja única en sus documentos. Si dos de ellos tienen id = 2, eso es un problema. En su lugar, es necesario utilizar el campo
_id
siid
. CouchDB garantizará la exclusividad, pero también, el resto de este plan requiere_id
para obtener documentos por ID.{ "type" : "el", "_id" : "1", "content" : "first" } { "type" : "el", "_id" : "2", "content" : "second" } { "type" : "el", "_id" : "3", "content" : "third" }
Si cambiar los documentos para usar
_id
es absolutamente imposible, puede crear una vista simple paraemit(doc.id, doc)
y luego volver a insertar eso en una base de datos temporal. Esto convierteid
en_id
pero agrega cierta complejidad.La vista emite
{"_id": content_id}
datos codificados en[list_id, sort_number]
, para "agrupar" las listas con su contenido.function(doc) { if(doc.type == ''list'') { for (var i in doc.elements) { // Link to the el document''s id. var id = doc.elements[i]; emit([doc.id, i], {''_id'': id}); } } }
Ahora hay una lista simple de los documentos, en el orden correcto. Puede usar las
startkey
yendkey
si desea ver solo una lista en particular.curl localhost:5984/x/_design/myapp/_view/els {"total_rows":2,"offset":0,"rows":[ {"id":"036f3614aeee05344cdfb66fa1002db6","key":["abc123","0"],"value":{"_id":"2"}}, {"id":"036f3614aeee05344cdfb66fa1002db6","key":["abc123","1"],"value":{"_id":"1"}} ]}
Para obtener
el
contenido de el, consulta coninclude_docs=true
. A través de la magia de_id
, los documentos se cargarán.curl localhost:5984/x/_design/myapp/_view/els?include_docs=true {"total_rows":2,"offset":0,"rows":[ {"id":"036f3614aeee05344cdfb66fa1002db6","key":["abc123","0"],"value":{"_id":"2"},"doc":{"_id":"2","_rev":"1-4530dc6946d78f1e97f56568de5a85d9","type":"el","content":"second"}}, {"id":"036f3614aeee05344cdfb66fa1002db6","key":["abc123","1"],"value":{"_id":"1"},"doc":{"_id":"1","_rev":"1-852badd683f22ad4705ed9fcdea5b814","type":"el","content":"first"}} ]}
Aviso, esta es toda la información que necesita. Si su cliente es flexible, puede analizar la información de este JSON. El siguiente paso opcional simplemente lo reformatea para que coincida con lo que necesita.
Use una función
_list
, que simplemente formatea la salida de la vista. La gente los usa para generar XML o HTML, pero haremos que el JSON sea más conveniente.function(head, req) { var headers = {''Content-Type'': ''application/json''}; var result; if(req.query.include_docs != ''true'') { start({''code'': 400, headers: headers}); result = {''error'': ''I require include_docs=true''}; } else { start({''headers'': headers}); result = {''content'': []}; while(row = getRow()) { result.content.push(row.doc.content); } } send(JSON.stringify(result)); }
Los resultados coinciden. Por supuesto, en producción necesitará una
startkey
y una deendkey
para especificar la lista que desea.curl -g ''localhost:5984/x/_design/myapp/_list/pretty/els?include_docs=true&startkey=["abc123",""]&endkey=["abc123",{}]'' {"content":["second","first"]}
Estoy buscando un CouchDB equivalente a "SQL joins".
En mi ejemplo, hay documentos CouchDB que son elementos de lista:
{ "type" : "el", "id" : "1", "content" : "first" }
{ "type" : "el", "id" : "2", "content" : "second" }
{ "type" : "el", "id" : "3", "content" : "third" }
Hay un documento que define la lista:
{ "type" : "list", "elements" : ["2","1"] , "id" : "abc123" }
Como puede ver, el tercer elemento fue eliminado, ya no es parte de la lista. Por lo tanto, no debe ser parte del resultado. Ahora quiero una vista que devuelva los elementos de contenido, incluido el orden correcto.
El resultado podría ser:
{ "content" : ["second", "first"] }
En este caso, el orden de los elementos ya está como debería ser. Otro posible resultado:
{ "content" : [{"content" : "first", "order" : 2},{"content" : "second", "order" : 1}] }
Empecé a escribir la función de mapa:
map = function (doc) {
if (doc.type === ''el'') {
emit(doc.id, {"content" : doc.content}); //emit the id and the content
exit;
}
if (doc.type === ''list'') {
for ( var i=0, l=doc.elements.length; i<l; ++i ){
emit(doc.elements[i], { "order" : i }); //emit the id and the order
}
}
}
Esto es todo lo lejos que puedo llegar. ¿Puedes corregir mis errores y escribir una función de reducción? Recuerde que el tercer documento no debe ser parte del resultado.
Por supuesto, también puedes escribir una función de mapa diferente. Pero la estructura de los documentos (un documento de elemento definido y un documento de entrada para cada entrada) no se puede cambiar.
EDITAR: No se pierda el comentario de Jason Smith sobre su respuesta, donde describe cómo hacerlo más corto.