Couchbase Móvil soporta un modelo de datos NoSQL estilo documento JSON. Además de soportar los tipos de datos JSON estándar, Couchbase Mobile también soporta datos binarios que incluyen imágenes, audio, vídeo, archivos PDF, etc. Un documento JSON puede asociarse a uno o más elementos de datos binarios denominados "adjuntos" o "blobs". Los datos binarios pueden ser sincronizados entre los clientes de Couchbase Lite y el servidor a través del Sync Gateway. En este post, discutiremos cómo crear adjuntos de datos binarios, cómo recuperarlos y actualizarlos. También echaremos un vistazo a cómo se representan internamente los adjuntos, las idiosincrasias relacionadas y cómo lidiar con ellas.
Todo en este post se aplica a un despliegue basado en Couchbase Mobile 2.x.
Antecedentes: Adjuntos y Blobs
El soporte para asociar datos binarios con documentos JSON dentro de Couchbase Mobile ha evolucionado a lo largo de los años. La representación interna de datos binarios dentro del documento JSON ha cambiado a través de las versiones de Couchbase Mobile. En Couchbase Mobile 1.x, los datos binarios se almacenaban en forma de "adjuntos" dentro de un documento de nivel superior "_archivos adjuntos". Couchbase Mobile introdujo el atributo blob para almacenar datos binarios. En la mayoría de los casos, la discrepancia entre las representaciones a través de versiones es manejada sin problemas por Couchbase Mobile, por lo que los usuarios finales no tienen que hacer nada especial dentro de sus aplicaciones para hacer frente a ella. Sin embargo, hay ciertos casos en los que los desarrolladores de aplicaciones tendrían que tomar medidas adicionales para hacer frente a la discrepancia. También discutiremos esas medidas en este post y trataremos de responder a algunas de las preguntas más frecuentes.
Flujo de trabajo #1: Gestión de archivos adjuntos creados en Couchbase Lite
Veamos cómo puedes crear documentos JSON con datos binarios adjuntos con Couchbase Lite y sincronizarlos con el servidor. Este es el flujo que vamos a describir:

Crear adjuntos de datos binarios en Couchbase Lite
Los desarrolladores deben utilizar el API de blobs para crear datos blob. Un documento puede asociarse con uno o más adjuntos o blobs. He aquí un fragmento de código que muestra el uso de esta API en swift. Consulte la documentación para desarrolladores para obtener fragmentos de código equivalentes para otras plataformas.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
deje mutableDoc = MutableDocument.init(id: "usuario::priya") si deje profileImage = UIImage(llamado: "perfil.jpg"), deje imageData = UIImageJPEGRepresentation(profileImage, 0.75) { deje blob = Blob(contentType: "image/jpeg", datos: imageData) mutableDoc.setBlob(blob, forKey: "imagen") } // ... Añadir otras propiedades mutableDoc.setString("usuario", forKey: "tipo") mutableDoc.setString("Priya", forKey: "nombre") mutableDoc.setString(" priya.rajagopal@couchbase.com, forKey: "correo electrónico") do { ¿intentar? db.guardarDocumento(mutableDoc) } captura { imprimir("Error en ahorro documento : (error)") } |
Representación interna
Cuando el documento se crea en Couchbase Lite, internamente, se ve algo como esto:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
{ "email": "priya.rajagopal@couchbase.com", "imagen": { "longitud": 3888349, "digest": "sha1-4xlj1AKFgLdzcD7a1pVChrVTJIc=", "tipo_contenido": "image/jpeg", "@tipo": "blob" }, "tipo": "usuario", "nombre": "Priya", "id": "usuario::priya", "rev": "1–1c8502034001b333cc469fe8c4c39e112eedf8a3" } |
Fíjese en el "@type": "blob" entrada de tipo creada para los datos del tipo de imagen.
Nota que hay varios metadatos a nivel de sistema como _id que se incluyen en el documento. Por brevedad, no se muestra todo en el ejemplo. Las aplicaciones nunca deben hacer suposiciones sobre el formato y la disponibilidad de los metadatos a nivel de sistema y, por esa razón, las aplicaciones nunca deben acceder a esos atributos directamente. Utilice siempre las opciones de recuperación de metadatos como meta().id.
Sincronización de archivos adjuntos con Sync Gateway
Sync Gateway es compatible con Couchbase Mobile 1.x. Esto implica que Sync Gateway debe ser capaz de procesar datos binarios utilizando la versión 1.x _. archivos adjuntos así como la representación 2.x blob tipo. Esto también implica que cuando el cliente Couchbase Lite 2.x envía datos a la puerta de enlace de sincronización, necesita enviarlos en un formato que sea compatible con los clientes 1.x.
Por esa razón, cuando Couchbase Lite sincroniza el documento con la Sync Gateway, añade la propiedad _archivos adjuntos en el documento. Así, el documento, una vez introducido, tendría un aspecto similar al del ejemplo siguiente. La lista de anexos asociados al documento se especifica en el campo Adjuntos objeto.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
<em><código>{ "archivos adjuntos": { "blob/image": { "tipo_contenido": "image/jpeg", "digest": "sha1-4xlj1AKFgLdzcD7a1pVChrVTJIc=", "longitud": 3888349, "revpos": 1, "talón": verdadero } }, "email": "priya.rajagopal@couchbase.com", "imagen": { "@tipo": "blob", "tipo_contenido": "image/jpeg", "digest": "sha1-4xlj1AKFgLdzcD7a1pVChrVTJIc=", "longitud": 3888349 }, "nombre": "Priya", "tipo": "usuario", "id": "usuario::priya", "rev": "1–1c8502034001b333cc469fe8c4c39e112eedf8a3", }</código></em> |
Nota que hay varios metadatos a nivel de sistema como _id que se incluye en el documento. En aras de la brevedad, no se muestra todo en el ejemplo. Las aplicaciones nunca deben hacer suposiciones sobre el formato y la disponibilidad de los metadatos a nivel de sistema y, por esa razón, las aplicaciones nunca deben acceder a esos atributos directamente. Utilice siempre las opciones de recuperación de metadatos como meta().id.
Recuperación de archivos adjuntos en Sync Gateway
Los datos adjuntos deben recuperarse a través de Sync Gateway _archivos adjuntos REST endpoint. En el momento de escribir este post, los archivos adjuntos no se pueden gestionar directamente utilizando los SDK de Couchbase Server.
A continuación se muestra un ejemplo de comando curl para recuperar los archivos adjuntos asociados a un documento utilizando la función _archivos adjuntos REST. Sustituiría la cabecera de autorización por las credenciales adecuadas correspondientes al usuario configurado en su sistema. Además, fíjese en el nombre del archivo adjunto, "mancha_%2Fimage” is the URL encoded version of "blob/imagen"_.
1 2 3 4 |
rizo -X GET 'http://sync-gateway-url:4984/dbname/user::priya/blob_%2Fimage' -H 'Accept: application/json' -H 'Autorización: Basic ZGVtbzpwYXNzd29yZA==' |
Actualización de archivos adjuntos en Sync Gateway
Los datos adjuntos deben actualizarse a través de Sync Gateway _archivos adjuntos REST endpoint. En el momento de escribir este post, los archivos adjuntos móviles no se pueden gestionar mediante los SDK de Couchbase Server.
A continuación se muestra un ejemplo de comando curl para actualizar un archivo adjunto asociado a un documento utilizando la función _archivos adjuntos REST. Sustituya la cabecera de autorización por las credenciales adecuadas correspondientes al usuario configurado en su sistema. Además, observe que la cabecera "rev" . Este parámetro corresponde a la revisión del documento que debe actualizarse. Puede recuperar el revId utilizando la función GET documento REST.
1 2 3 4 5 6 |
rizo -i -X PUT 'http://sync-gateway-url:4984/dbname/user::priya/blob_%2Fimage?rev=12-fa2bf00dab7e811eb562a502429ec633' -H 'Accept: application/json' -H 'Autorización: Basic ZGVtbzE6cGFzc3dvcmQ=' -H Tipo de contenido: image/png -H 'cache-control: no-cache' -datos-binario "@layered.png" |
Pero... espera... ¡un desajuste!
Ahora, después de actualizar el archivo adjunto, si recupera el documento utilizando la función GET documento REST,
1 2 3 4 5 6 |
rizo -X GET 'http://sync-gateway-url:4984/dbname/user::priya/blob_%2Fimage' -H 'Accept: application/json' -H 'Autorización: Basic ZGVtbzE6cGFzc3dvcmQ=' -H Content-Type: application/json' -H 'cache-control: no-cache' |
La respuesta correspondiente sería algo así
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
{ "archivos adjuntos": { "blob/image": { "tipo_contenido": "imagen/png", "digest": "sha1-XeeXt0I014+1qpH+s2S2AUSg4II=", "longitud": 3444504, "revpos": 16, "talón": verdadero } }, "id": "usuario::demo1", "rev": "13-e61d1a9e63069030212007a8b5eddde9", "dirección": "", "email": "demo1", "imagen": { "@tipo": "blob", "tipo_contenido": "image/jpeg", "digest": "sha1-4xlj1AKFgLdzcD7a1pVChrVTJIc=", "longitud": 3888349 }, "nombre": "Priya Rajagopal", "tipo": "usuario" } |
Observará que el _attachment y blob no coinciden. Mientras que la _attachment apunta a la última imagen, la blob sigue describiendo la imagen antigua. Pero está bien.!
La razón de esta discrepancia se debe a que Sync Gateway sólo trabaja con archivos adjuntos de estilo 1.x.
¿Cómo sigue funcionando esto?
Esto funciona porque en el contexto de la puerta de enlace de sincronización, que se ocupa de los archivos adjuntos de estilo 1.x, sólo se respeta la entrada del archivo adjunto.
¿Pero qué pasa con Couchbase Lite? ¿Qué pasa cuando el documento actualizado es sincronizado por el cliente Couchbase Lite 2.x?
Cuando el documento es replicado por el cliente Couchbase Lite 2.x, Couchbase Lite busca la presencia de Adjuntos y manchas dentro del documento e implementa la lógica adecuada para identificar que se trata de un documento de estilo 2.x creado por un cliente 2.x pero actualizado posteriormente por un cliente 1.x (como la API REST de Sync Gateway). Por lo tanto, trata el Adjuntos como el archivo adjunto "real" y unifica la entrada blob correspondiente.
Desde el punto de vista del desarrollador, todo esto se gestiona automáticamente. Así que realmente no tienes que preocuparte por ninguno de los detalles. Como desarrollador, tendrías que saber cómo recuperar el archivo adjunto actualizado desde dentro de la aplicación habilitada para Couchbase Lite.
Recuperación de archivos adjuntos actualizados en Couchbase Lite
Cuando el archivo adjunto actualizado se sincronice con su aplicación Couchbase Lite, utilice la función API de Blob para recuperar los datos. Aquí hay un fragmento de código que muestra el uso de esta API en swift. Consulte la documentación para desarrolladores para obtener fragmentos de código equivalentes para otras plataformas.
1 2 3 4 5 6 |
si deje doc = db.documento(conID: "usuario::priya") { deje blobValue = doc.blob(forKey:"imagen")?.contenido // utilizar el blobValue } |
Ahora veamos el flujo inverso.
Flujo de trabajo #2: Gestión de archivos adjuntos creados en Sync Gateway
Veamos cómo crear documentos JSON con datos binarios adjuntos en Sync Gateway y sincronizarlos con Couchbase Lite.
Este es el flujo que vamos a describir -

Crear archivos adjuntos de datos binarios en el servidor
Para adjuntar datos binarios en el lado del servidor Couchbase que puedan sincronizarse con los clientes a través de la puerta de enlace de sincronización, deberá utilizar la puerta de enlace de sincronización punto final REST de archivos adjuntos. En el momento de escribir este post, los archivos adjuntos compatibles con móviles no se pueden crear directamente utilizando los SDK de Couchbase Server. Los datos adjuntos que se crean a través del punto final REST de Sync Gateway se mantienen en el bucket de Couchbase Server y se sincronizan con los clientes de Couchbase Lite sujetos a las políticas de control de acceso configuradas en Sync Gateway.
Para ello, cree primero un documento (o recupere un documento creado previamente) y, a continuación, cree el archivo adjunto para el documento. Otra posibilidad es crear un documento de varias partes con datos JSON y binarios. Pero esto podría resultar tedioso, ya que también habría que generar los metadatos pertinentes del archivo adjunto. Así que los pasos descritos a continuación es mi opción preferida
- Crear documento
Un documento JSON puede crearse directamente en el servidor Couchbase utilizando el SDK del servidor Couchbase o la interfaz de usuario de administración, o bien puede crearse utilizando la función Documento PUT API REST. El documento también podría haberse sincronizado desde un cliente Couchbase Lite.
A continuación se muestra un ejemplo de uso del punto final REST de Sync Gateway para crear un documento con Id. "usuario::jane". Deberá sustituir el encabezado de autorización por las credenciales adecuadas correspondientes al usuario configurado en su instalación.
1 2 3 4 5 6 7 8 9 10 |
rizo -X PUT http://sync-gateway-url:4984/dbname/user::jane/ -H 'Accept: application/json' -H 'Autorización: Basic ZGVtbzpwYXNzd29yZA==' -H Content-Type: application/json' -d '{ "email": "jane.doe@example.com", "tipo": "usuario", "nombre": "Jane Doe" }' |
La respuesta sería algo parecido a lo siguiente
1 2 3 4 5 |
{ "id": "usuario::jane", "ok": verdadero, "rev": "1-ed2d37e7ece0dc5726fecd211433cbba" } |
- Crear anexo para documento en Sync Gateway
Los datos adjuntos deben crearse a través de Sync Gateway _archivos adjuntos REST endpoint. Este paso es idéntico al flujo anterior cuando se actualizaba un anexo a través del punto final REST.
A continuación se muestra un ejemplo de comando curl para actualizar un archivo adjunto asociado a un documento utilizando la función _archivos adjuntos REST. Deberá sustituir la cabecera de autorización por las credenciales adecuadas correspondientes al usuario configurado en su instalación. La dirección "rev" . Este parámetro corresponde a la revisión del documento que debe actualizarse.
1 2 3 4 5 6 |
rizo -i -X PUT 'http://sync-gateway-url:4984/dbname/user::jane/blob_%2Fimage?rev=1-ed2d37e7ece0dc5726fecd211433cbba' -H 'Accept: application/json' -H 'Autorización: Basic ZGVtbzE6cGFzc3dvcmQ=' -H Tipo de contenido: image/png -datos-binario "@en capas.png" |
Representación interna
Cuando el documento sea actualizado por la pasarela de sincronización, tendrá el siguiente aspecto
Si recupera el documento mediante la función GET documento REST,
1 2 3 4 5 6 |
rizo -X GET 'http://sync-gateway-url:4984/dbname/user::jane/blob_%2Fimage' -H 'Accept: application/json' -H 'Autorización: Basic ZGVtbzE6cGFzc3dvcmQ=' -H Content-Type: application/json' -H 'cache-control: no-cache' |
La respuesta correspondiente sería algo así
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
<em><código>{ "archivos adjuntos": { "blob/image": { "tipo_contenido": "imagen/png", "digest": "sha1-VteI8PPA3tFVxeW8z2qoJpQo40Y=", "longitud": 1768, "revpos": 2, "talón": verdadero } }, "id": "usuario::jane", "rev": "2–95da324bd67db252d8b682cd113e3879", "email": "jane.doe@example.com", "tipo": "usuario", "nombre": "Jane Doe" }</código></em> |
La creación de archivos adjuntos mediante la API REST de archivos adjuntos de Sync Gateway dará como resultado la representación de archivos adjuntos de estilo 1.x. Observa que no hay metadatos "blob" estilo 2.x. Esto es importante cuando accedes al documento en Couchbase Lite.
Recuperación de archivos adjuntos actualizados en Couchbase Lite
Cuando el documento creado previamente se sincroniza con el lado de Couchbase Lite, detecta que se trata de un documento de estilo 1.x y deja el campo Adjuntos intacta. Trata los objetos anidados dentro del Adjuntos como blobs. Sin embargo, el documento no se actualiza automáticamente para incluir la entrada "blob" que se añade. Por lo tanto, la aplicación deberá buscar la presencia de blobs mediante la función API de Blob en ambos lugares.
1 2 3 4 5 6 7 8 9 10 11 |
// Primero busca el blob en la entrada blob de nivel superior si deje imageVal = userVal.blob(forKey:"imagen")?.contenido { // imageVal contiene el archivo adjunto } si no { // Manejar la campabilidad con archivos adjuntos creados a través de la API Sync Gateway // Esos archivos adjuntos se crean con el estilo 1.x. deje archivos adjuntos = userVal.diccionario(forKey: "archivos adjuntos") deje imageVal = archivos adjuntos?.blob(forKey:"blob/image")?.contenido // imageVal contiene el archivo adjunto } |
PREGUNTAS FRECUENTES
Para terminar, he recopilado una lista de preguntas frecuentes relacionadas con el manejo de adjuntos en Couchbase Mobile
¿Dónde se guardan los archivos adjuntos?
En Couchbase Lite, los adjuntos se almacenan en la instancia de base de datos de Couchbase Lite que contiene el documento correspondiente. Se almacena separadamente del documento que contiene los metadatos asociados que contienen la referencia al adjunto. Si el mismo adjunto es compartido por múltiples documentos, sólo una instancia del adjunto es almacenada en la base de datos.
En Couchbase Server, los adjuntos se almacenan en el mismo bucket de Couchbase Server que el documento correspondiente. Se almacenan separados del documento que contiene los metadatos asociados que contienen la referencia al adjunto. Si el mismo adjunto es compartido por múltiples documentos, sólo una instancia del adjunto es almacenada en el bucket.
¿Existe un límite en el número de archivos adjuntos que pueden asociarse a un documento?
Puede adjuntar uno o varios anexos a un documento JSON. No hay límites estrictos en el número de archivos adjuntos que se pueden asociar a un documento. Sin embargo, dado que los metadatos adjuntos se almacenan en las xattrs del documento (cuando shared_bucket_access está habilitado) el número de adjuntos está limitado por el tamaño de metadatos de sincronización permitido por documento. Dado que los metadatos adjuntos oscilan entre 100 y 200 bytes y que el límite de tamaño de los metadatos de sincronización es de 1 MB por documento, existen límites prácticos en cuanto al número de archivos adjuntos que se pueden asociar a un documento.
¿Cuál es el tamaño máximo de un archivo adjunto?
El tamaño máximo de cada archivo adjunto es de 20 MB. Esto se debe a los límites de tamaño de los documentos en Couchbase Server. Mientras que Couchbase Lite permite adjuntos de tamaño superior a 20MB y esto está bien siempre y cuando el adjunto sea sólo local y se garantice que nunca será sincronizado con el servidor. Sin embargo, se advierte a los desarrolladores que no creen archivos adjuntos tan grandes, ya que serán rechazados por el Sync Gateway.
¿Se sincronizan los archivos adjuntos cada vez que cambia el documento JSON asociado?
El protocolo de replicación está optimizado para sincronizar adjuntos sólo cuando hay actualizaciones en ellos. Esto implica que no son empujados o tirados por los clientes de Couchbase Lite incluso si hay actualizaciones de otros datos en los documentos JSON asociados.
¿Cómo gestiona el protocolo los fallos al sincronizar archivos adjuntos?
El protocolo es muy robusto en términos de manejo de fallos de sincronización, por ejemplo debido a interrupciones de la red. Los documentos no se guardan en el Sync Gateway o en Couchbase Lite hasta que todos los archivos adjuntos o blobs asociados se hayan sincronizado correctamente. Por lo tanto, podría haber una ventana de tiempo en la que podrías acabar con adjuntos/blogs huérfanos que no tienen documentos asociados. Eso no es un problema porque la sincronización subsiguiente del documento reconocerá que el adjunto ya está persistente y no intentará resincronizarlo de nuevo.
El futuro
Couchbase Mobile proporciona una interfaz fácil de usar para gestionar archivos adjuntos. Echa un vistazo a la documentación para más detalles sobre el manejo de blobs en cada una de las plataformas.
Si tiene alguna pregunta o sugerencia, deje un comentario a continuación o póngase en contacto conmigo a través de Twitter o envíame un correo electrónico. En Foros de desarrollo de Couchbase son un gran lugar para relacionarse con la comunidad de desarrollo de Couchbase.
Hola Priya,
He aquí otra pregunta para las FAQ, si es posible.
Dado que los BLOBs o archivos adjuntos son binarios y no pueden ser procesados, buscados, comprimidos, diff'd, etc. ¿Por qué se almacenan en una enorme base de datos en lugar de en una carpeta con un nombre de archivo único?
¿Es posible tener una carpeta que contenga un sitio web gestionando su base de datos-documentos-contenidos que se replican a los múltiples nodos?
Hola
Depende del caso de uso. Si estás hablando de grandes volúmenes de datos binarios, entonces almacenarlos en un CDN/almacén externo es la opción preferida. En ese caso, almacenarás datos binarios externos al servidor Couchbase e incluirás la URL de referencia en el documento. La aplicación se encargará de bajar y subir los archivos adjuntos y de actualizar las referencias correspondientes al documento cuando se detecten dichos cambios.
La ventaja de tratar los archivos adjuntos binarios como "documentos" es que se obtienen garantías de coherencia (eventual), ya que nuestro protocolo de sincronización se encarga de enviar y recibir los archivos. Nosotros nos encargamos de detectar los cambios en los archivos adjuntos y de extraer los cambios cuando sea necesario.
Incluso si eliges almacenar los adjuntos en un almacén externo para evitar almacenarlos en el bucket del servidor, si estás buscando la capacidad offline-first, necesitarás persistir localmente los adjuntos en Couchbase lite para que estén disponibles incluso cuando el cliente esté offline.
Por cierto, los datos binarios se comprimen bien.
Hola Priya,
No puedo entender por qué los SDK de Couchbase Server no ofrecen una opción para añadir directamente archivos adjuntos (blobs) y tenemos que pasar por la pasarela de sincronización. ¿Podría explicarnos esto? ¿Hay planes de añadir esta opción en futuras versiones?
Lo mejor,
PShri
Hola
El soporte para el uso de CBS SDK para la creación de datos binarios que se pueden sincronizar con los clientes couchbase lite está en nuestro radar. Mientras tanto, el patrón típico es crear el documento a través del SDK y utilizar el punto final REST de Sync Gateway para asociar archivos adjuntos/datos binarios.
¿Cómo puedo saber cuándo se añade al SDK de CBS? ¿Hay algún sitio donde pueda suscribirme y enterarme? Gracias por su tiempo.
No estoy seguro de haber entendido la pregunta. El mismo cliente SDK que está escribiendo el documento en el bucket del servidor será el responsable de utilizar el endpoint REST para asociar/crear el adjunto. Así, en lugar de una única llamada para crear el documento y el adjunto, el cliente SDK realizará dos llamadas: una llamada INSERT/UPSERT para crear el documento en el bucket seguida de la API REST _attachment para crear el adjunto asociado al documento.
Hola Priya,
¿Propone alguna otra forma de admitir archivos adjuntos de gran tamaño (> 20 MB)?
¿es posible dividir el archivo adjunto que grater de 20 MB?
Gracias
Si tiene archivos adjuntos tan grandes, se recomienda almacenarlos en una CDN externa y pegar la URL en el documento. Probablemente no quieras almacenar datos binarios tan grandes en una base de datos. Tu aplicación sería la responsable de gestionar los archivos adjuntos. No hay ningún mecanismo integrado para agrupar y combinar los archivos adjuntos.