2010-11-27 12 views
8

Publiqué esto en la lista de correo de CouchDB-Usuarios, pero pensé que podría ampliar mi red un poco más.Vistas de CouchDB: uniones y subconsultas

[enlaces destruidos debido a las nuevas reglas de spam de usuario de stackoverflow :-(]

Esperemos que uno de ustedes la gente inteligente puede ayudar (o al menos alguien puede definitivamente me diga lo que estoy tratando de hacer es imposible, y voy a tengo que mirar en alternativas ... he oído MySQL está en la captación. (-:) información

Antecedentes: he creado una base de datos de ejemplo aquí: scoates-test.couchone.com /_utils/database.html?follow /scoates-test.couchone.com/follow

Tengo dos tipos de documentos. tipo = usuario y tipo = activo.

Ejemplo usuario: scoates-test.couchone.com/_utils/document.html?follow/c988a29740241c7d20fc7974be05f67d

Ejemplo activo: scoates-test.couchone.com/_utils/document.html?follow/c988a29740241c7d20fc7974be061d62

Los usuarios pueden seguir a otros usuarios (el tipo = campo "siguiente" del documento de usuario). El ejemplo usuario anterior (nombre de usuario = bob) es "siguientes" 2 usuarios:

"following": [ 
    "c988a29740241c7d20fc7974be05ec54", // username=aaron 
    "c988a29740241c7d20fc7974be060bb4" // username=dale 
] 

activos son propiedad de un usuario específico. El activo de ejemplo anterior es propiedad de c988a29740241c7d20fc7974be061d62 (username = bob).

Espero que tenga sentido.

Me gustaría solicitar recursos que pertenezcan a los usuarios que bob está siguiendo (aaron y dale), y No puedo poner el dedo en el código de vista que lo permita. Puedo emitir fácilmente todos los activos que pertenecen a c988a29740241c7d20fc7974be05f67d.

I podría hacerlo en dos solicitudes. En primer lugar, le preguntaría a CouchDB por c988a29740241c7d20fc7974be05f67d, y luego escriba lo siguiente como "claves" de una vista que devuelve activos que pertenecen a esas claves, pero notará que mis documentos type = asset también tienen un campo "when" , y quiero poder ordenarlo al emitir [doc.owner, doc.when] como la clave, y luego usar startKey/endKey. Así que el POST de llaves está fuera, creo.

que podría simplemente se unen en el lado de la aplicación (consultar las siguientes teclas, hacer una solicitud de cada una de estas teclas, a continuación, ordenar en el lado de la aplicación), pero esto rompe la paginación realmente mal (yo necesidad solicitar un límite de pageSize para cada siguiente), y eso se sale de control muy rápidamente (si un usuario está siguiendo a 1000 usuarios, eso es 10,000 registros por página).

Ninguna de estas soluciones funciona para mí. Me gustaría hacerlo en CouchDB.

Estoy realmente perplejo. Por favor ayuda.

S

Respuesta

10

Hay una regla fundamental para CouchDB vistas, que pueden ayudar a resolver este tipo de problema.

Consultar una vista CouchDB devuelve cero, uno o más tuplas clave-valor-id de tal manera que la tecla, el valor y el ID se calculan a partir del mismo documento. Opcionalmente, puede solicitar el documento con la identificación proporcionada (que puede o no ser el documento que se utilizó para calcular la tupla).

Si se piensa en ello, es bastante lógico: cada tupla es la consecuencia de una emit(), por lo que todos los datos emitidos sólo puede venir de un solo documento.

En su caso específico, necesita la clave tupla que contiene:

  • El usuario actual, ya que sólo quiere documentos visibles por ese usuario
  • del documento "propietario", porque es necesario para ordenar por ese valor.
  • El documento es "cuando", porque debe ordenar por ese valor.

De acuerdo con la regla fundamental, necesita un solo documento CouchDB para contener todo esto. Su esquema actual (usuario actual y propietario del documento en el documento "usuario", propietario del documento y cuando está en el documento "documento") no reúne los datos requeridos, por lo que debe cambiarlo.

Mi sugerencia sería utilizar un documento de "compartir" con la siguiente estructura:

{ 
    owner : 'id-of-aaron', 
    followers : [ 'id-of-bob', 'id-of-mike', 'id-of-melissa' ], 
    docs : { 
    'id-of-doc-1' : '2010-09-08', 
    'id-of-doc-2' : '2010-09-07', 
    'id-of-doc-3' : '2010-11-27' 
    } 
} 

Es necesario mantener esta estructura actualizada cada vez que un usuario sigue/unfollows el propietario, o el propietario añade o elimina una documento. Desde allí, puede simplemente emitir:

for (var docid in doc.docs) 
    for (var i in doc.followers) { 
    emit ([doc.followers[i], doc.owner, doc.docs[docid]], { _id : docid }); 
    } 
} 
+0

Gracias por la respuesta, voy a pensar en esto. Si satisface mis necesidades, regresaré y acepto su respuesta. Si no, volveré y haré algunas preguntas de seguimiento (-: – scoates

+0

¡Gracias! Esto funciona. Realmente aprecio que se tome el tiempo de darme una buena solución. – scoates

+0

Sería maravilloso si pudiera echar un vistazo en mi pregunta de seguimiento, también. ¡Gracias! http://stackoverflow.com/questions/4298937/couchdb-views-remove-duplicates-and-order-by-time – scoates

Cuestiones relacionadas