¿Qué diferencia un almacén de documentos de un almacén de valores clave?
Una base de datos de documentos puede consultar y manipular el contenido de lo que almacena, mientras que el valor sigue siendo un misterio opaco para el almacén de clave-valor.
Con Couchbase Server 4.5, hemos introducido nuestra nueva API de sub-documento para darte un mayor acceso de consulta y mutación a la carne de tus documentos.
Subdocumentos básicos
¿Cuál es el resumen de las nuevas funciones de subdocumento de Couchbase?
- Recuperar partes de un documento.
- Cambia partes de un documento enviando los cambios a Couchbase Server.
- Disponible ahora en todos los SDK oficiales de Couchbase Server.
- Complementa la consulta ofrecida por las vistas y la consulta y las mutaciones ofrecidas por N1QL.
Bien, pasemos al por qué.
¿Por qué operaciones con subdocumentos?
Digamos que tenemos un documento JSON de 1 MB en Couchbase que almacena un registro de chat entre dos personas. Cada vez que los participantes en el chat escriben algo nuevo, queremos añadirlo al documento de registro.
Sin operaciones de subdocumento, necesitaríamos:
- Obtener el documento completo
- deserializarlo en su aplicación
- añadir la nueva línea de la conversación
- serializarlo de nuevo a JSON
- enviar el documento completo de vuelta a Couchbase para ser almacenado.
Usando el cliente Python de Couchbase, sería algo como esto:
|
1 2 3 |
rv = cb.consiga(chatlog) # Obtener el documento completo rv.doc.mensajes += [nvm lol] # Modificar el documento localmente cb.sustituir(rv.clave, rv.doc, cas=rv.cas) # Volver a cargar todo el documento |
Parece un derroche. Ahora piense en la velocidad a la que la gente suele chatear en las conversaciones de mensajería instantánea. Luego piensa en cuántos chats simultáneos podrían estar teniendo lugar.
Couchbase Server puede desempeñar felizmente su papel allí, pero pone una carga innecesaria en su red y le hace mantener código de aplicación para manejar lo que usted podría considerar razonablemente como funciones de la capa de base de datos.
Con las operaciones de subdocumento, tenemos que hacer mucho menos. Añadir una nueva línea a un registro de chat se parecería más a esto, de nuevo en Python:
|
1 2 |
importar couchbase.subdocumento como SD cb.mutar_en(chatlog, SD.añadir(mensajes, nvm lol)) |
Enviamos la nueva línea a Couchbase Server, especificando el documento y en qué parte del documento hacer el cambio.
De esta forma, conseguimos evitar un viaje de ida y vuelta, ahorrar ancho de banda de red enviando sólo lo que ha cambiado y trasladar la responsabilidad de actualizar el documento de la aplicación a la capa de base de datos.
Funcionamiento de las operaciones con subdocumentos
El SDK de Couchbase utiliza tres APIs para trabajar con Couchbase Server:
- clave-valor, utilizando el protocolo binario memcached
- vistas, utilizando el protocolo REST de CouchDB
- N1QL, utilizando el protocolo REST de N1QL.
El SDK abstrae los detalles pero, si has trabajado con Couchbase Server, sabrás qué tipo de interacción estás teniendo.
Las operaciones con subdocumentos se realizan utilizando una extensión del protocolo memcached que gestiona sus operaciones clave-valor.
Encontrar su subdocumento
Para realizar una operación de subdocumento se necesitan dos cosas:
- la clave del documento
- la ruta del subdocumento dentro del documento padre.
¿Qué entendemos por camino?
La ruta es la ubicación dentro del documento donde quieres hacer algo y es la misma notación utilizada por N1QL.
Digamos que estamos trabajando con perfiles de clientes para una tienda online sencilla. He aquí un ejemplo de documento de perfil:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
{ "nombre": "Douglas Reynholm", "email": "douglas@reynholmindustries.com", "direcciones": { "facturación": { "línea1": "Calle Cualquiera 123", "línea2": "Cualquier ciudad", "país": "Reino Unido" }, "entrega": { "línea1": "Calle Cualquiera 123", "línea2": "Cualquier ciudad", "país": "Reino Unido" } }, "compras": { "completo": [ 339, 976, 442, 666 ], "abandonado": [ 157, 42, 999 ] } |
La ruta del campo país en la dirección de entrega de nuestro cliente sería:
|
1 2 |
direcciones.entrega.país |
Del mismo modo, si las compras se enumeran de nueva a antigua, para encontrar el id de la segunda compra más reciente del cliente utilizaríamos:
|
1 2 |
compras.completa[1] |
Por lo tanto, nuestro subdocumento es cualquier parte del documento que se encuentre en la ruta que proporcionamos. Podría ser un objeto enorme o un solo índice en una matriz.
Utilización de operaciones con subdocumentos
A nivel de cubo, las cosas son muy sencillas. Sólo hay dos métodos nuevos:
- buscarEn(clave)
- mutateIn(clave).
En el SDK de Java se implementa utilizando el patrón constructor. Así, estos dos métodos de cubo crean para nosotros un objeto, ligado a un documento en particular, donde podemos hacer el trabajo real de consultar o cambiar nuestro sub-documento.
Veamos un ejemplo en Java, en el que buscamos la dirección de entrega de nuestro cliente.
|
1 2 |
LookupInBuilder constructor = couchbase.cubo().buscarEn(cliente123); |
En primer lugar, vamos a crear un objeto constructor que se ceba con el documento de nuestro cliente. A continuación, podemos realizar las operaciones de sub-documento en ese documento constructor.
|
1 2 3 |
constructor = constructor.consiga("direcciones.entrega"); DocumentoFragmento resultados = constructor.doLookup(); |
Si estamos utilizando el documento JSON de ejemplo de antes en este post, resultados será:
|
1 2 3 4 5 6 |
{ "línea1": "Calle Cualquiera 123", "línea2": "Cualquier ciudad", "país": "Reino Unido" } |
Podemos simplificar esta consulta encadenando todo el conjunto:
|
1 2 3 4 |
DocumentoFragmento resultados = couchbase.cubo().buscarEn(cliente123) .consiga("direcciones.entrega") .doLookup(); |
A medida que construimos consultas y mutaciones más complejas, podemos encadenar muchas operaciones. En el SDK de Java, doLookup indica el final de la consulta y la envía para su ejecución.
Como vimos anteriormente en el ejemplo de mensajería instantánea, también podemos modificar documentos utilizando la API de subdocumentos.
Digamos que queremos cambiar algunas partes de la dirección de facturación de nuestro cliente. En Python, podríamos utilizar la API de sub-documento para hacerlo así:
|
1 2 3 4 5 |
importar couchbase.subdocumento como SD cb.mutar_en(cliente123, SD.upsert(facturación.línea1, 123 Main St), SD.upsert(facturación.línea2, "En algún lugar)) |
Al igual que en Java, primero seleccionamos el documento por su clave y luego realizamos una serie de operaciones sobre su contenido.
Próximos pasos
Para obtener información detallada sobre cómo utilizar la API de subdocumentos en su idioma preferido, consulte la documentación actualizada del SDK.
También puedes leer el post de Mark, de próxima aparición, que entra en más detalles sobre el uso de la API de subdocumentos.