Esta entrada del blog se basa en un entrada anterior del blog de Jeff Morris que cubría la API de subdocumentos cuando aún estaba en versión preliminar para desarrolladores. Ha habido algunos cambios en la API desde ese lanzamiento.

Con Servidor Couchbase 4.5 y el .NET SDK 2.3.xahora puede utilizar la función Subdocumento en su aplicación .NET.

En versiones anteriores de Couchbase, todas las mutaciones de documentos eran atómicas e involucraban a todo el documento. Si sólo quieres cambiar un único campo y luego hacer una actualización, todo el documento en el servidor Couchbase es copiado por la nueva revisión. El problema es que si el documento es grande o la red lenta (o ambos), entonces se desperdician muchos recursos enviando datos que no han sido modificados. Una solución mejor y más eficaz sería enviar sólo la parte del documento o el valor que se ha modificado. Esencialmente, eso es lo que se consigue con la API de subdocumento; cuando se actualiza un elemento o se elimina un elemento de un documento, sólo se envía por cable la ruta del fragmento que se va a mutar y sólo se modifica esa parte del documento.

Subdocument

La API admite varias operaciones diferentes, desde mutaciones en elementos anidados individuales (también conocidas como sub-) a modificaciones de matrices y diccionarios. También se admiten operaciones de contador, así como operaciones de recuperación de fragmentos JSON incrustados.

La API se expone a través de un fluido que le permite añadir múltiples operaciones y ejecutarlas contra el documento de forma atómica. Existen dos "constructores" diferentes: un constructor para operaciones de mutación y un constructor para lecturas o "búsquedas" (que también puede comprobar si un elemento existe en una ruta determinada).

Requisito previo: Servidor Couchbase 4.5

Para poder seguir los ejemplos que se presentan a continuación, deberá descargar e instalar Servidor Couchbase 4.5. Si nunca has instalado Couchbase Server, puedes ver mi vídeo sobre cómo instalar Couchbase Server en Windows. Es muy fácil, independientemente del sistema operativo que utilices.

Descripción general de la API de subdocumentos

Los siguientes ejemplos utilizarán un documento con un id de "cachorro" y empezarán con este aspecto:

Todos los Los ejemplos están disponibles en Github para que puedas clonar el proyecto y jugar con la API.

MutateInBuilder y LookupInBuilder

La API de subdocumentos ofrece dos nuevos tipos que utilizan un patrón constructor a través de una interfaz fluida para encadenar varias operaciones en un documento. Ambos objetos se crean llamando a MutateIn o BúsquedaEn en un CouchbaseBucket e introduciendo la clave del documento con el que se está trabajando:

Una vez que tenga el objeto constructor, puede encadenar una serie de operaciones para ejecutarlas contra el documento, por ejemplo:

A continuación, puede enviar todas las operaciones al servidor en un único lote:

Puedes comprobar el resultado de una operación, utilizando OpStatus y una ruta. En este ejemplo, estoy usando la ruta "tipo":

Estos son algunos de los métodos y campos que encontrará en la aplicación IDocumentFragment interfaz.

Nombre

Descripción

Contenido(...)

Obtiene el contenido de una ruta o índice dados.

Existe(...)

Devuelve true si hay un resultado para una ruta o índice dados.

Contar()

El recuento de las operaciones en curso mantenidas por el constructor.

OpStatus(...)

En ResponseStatus de una operación en un índice o ruta determinados.

Estado

En ResponseStatus para toda la operación múltiple.

Éxito

Verdadero si la operación múltiple completa tiene éxito.

Además de estas propiedades o métodos, existen todas las demás propiedades heredadas de OperationResult (que es la respuesta estándar de una operación clave/valor): Upsert, Remove, Replace, etc.

Tratamiento de errores

Al enviar varios mutacionesSi una de ellas falla, falla toda la solicitud multioperación. Esto permite una semántica transaccional de "todo o nada" al realizar mutaciones dentro de un mismo documento.

Al enviar varios búsquedasAlgunas operaciones pueden tener éxito y otras pueden fallar, intentando el servidor devolver tantos elementos como se le soliciten.

Si la(s) operación(es) ha(n) fallado, elEstado contendrá una respuesta de error de nivel superior como SubDocMultiPathFailure. Esto es una indicación de que debe profundizar en los resultados de la operación para obtener el error específico. Puede hacerlo iterando: llamando a la función OpStatus y pasando el índice o la ruta:

En este caso, como la ruta "somepaththatdoesntexist" no existía dentro del documento, el error específico devuelto fue SubDocPathNotFound. Hay muchas combinaciones diferentes de errores dependiendo del tipo de constructor y de la condición del error.

Ejemplos de LookupInBuilder

En LookUpInBuilder admite dos operaciones: buscar un valor por ruta y comprobar la existencia de un valor en una ruta determinada.

Consíguelo:

Busquemos el propietario fragmento. Si paso "owner" como parámetro de ruta a este método...

...la salida a consola sería:

Existe:

También podemos comprobar si existe una ruta. Si paso "owner" como la ruta a este método...

...la salida es verdaderoporque el camino propietario existe efectivamente en el documento.

MutateInBuilder

MutateInBuilder ofrece una serie de métodos que permiten realizar mutaciones en valores escalares, diccionarios y matrices, así como operaciones de contador atómico.

Insertar:

Insertar añade un valor a un diccionario, permitiendo opcionalmente que se añada el elemento que lo contiene (el propio diccionario).

Si llamara al método anterior así

El diccionario de atributos del documento tendrá ahora este aspecto:

Tenga en cuenta que el Inserte tiene un parámetro booleano opcional llamado crearPadres. Es falso por defecto. Si es verdadero, la API de subdocumentos creará la ruta necesaria para que exista el campo. Si es falso, la API de subdocumentos sólo creará el campo si los padres del campo ya existen. En el ejemplo anterior, el campo atributos ya existía.

En el siguiente ejemplo, utilizaré una ruta con un campo padre (unnuevoatributo) que no exista ya.

Esto creará el nuevo atributo llamado unnuevoatributo en el documento y añadir una única clave llamada conakey con un valor de algún valor.

Ahora, si pasamos falso para crearPadres y el atributo padre no existiera, la mutación múltiple fallaría con un estado de respuesta de nivel superior de SubDocMultiPathFailure y el error específico sería SubDocPathNotFound.

Upsert

Upsert añadirá o sustituirá una entrada del diccionario existente. El uso es exactamente el mismo que Inserte con la excepción de que el nombre del método es Upsert.

Eliminar

Eliminar eliminará un elemento en una ruta determinada.

Cuando llamo a este método:

Este es el aspecto que tendrá el documento después:

Sustituir

Reemplazar intercambiará el valor del elemento en una ruta dada, fallando si la ruta no existe:

Después de llamar a este método:

El documento tendrá ahora un valor diferente para "propietario":

ArrayAppend

ArrayAppend añade un valor al final de un array, añadiendo opcionalmente el elemento padre (el propio elemento del array) si no existe.

Después de ese método con la ruta "juguetes"...

...el juguetes del documento tendrá el valor "zapatilla" en el último ordinal:

ArrayPrepend

ArrayPrepend funciona de la misma manera que ArrayAppend, excepto que añade un valor a la variable frente de una matriz.

Llamando a ese método con la ruta "juguetes"...

En juguetes tiene ahora el valor "slipper" en su matriz primero ordinal:

ArrayInsert

ArrayPrepend pone un valor al principio, ArrayAppend lo pone al final. Para redondear las cosas, puedes usar ArrayInsert para poner un valor en algún punto intermedio (en un índice dado).

Y luego llamar a ese método con "juguetes[2]"...

En juguetes tiene ahora el valor "zapatilla" en su ordinal 3 (índice 2):

ArrayAddUnique

ArrayAddUnique insertará un valor en un array, pero fallará si ese valor ya existe (es decir, el valor debe ser único dentro del array).

Cuando llamo a eso con "zapato"...

...puesto que el valor "shoe" ya existe en el documento original de juguetes esto fallará con el estado SubDocPathExists.

Tenga en cuenta que este método sólo permite insertar primitivas JSON: cadenas, números y valores especiales para true, false o null. No hay forma de comparar la unicidad sin descender a cada objeto JSON y comparar los elementos elemento por elemento.

Contador

Añade el delta (cambio) especificado a un valor existente, creando el elemento si no existe. Por defecto, tanto el valor como el delta serán 0. Si el delta es negativo, el valor del elemento se disminuirá en el delta dado.

Crearé un método que utilice Contador:

Entonces, llamaré al método dos veces usando un 1 positivo y un 1 negativo como los "deltas":

Después de la primera llamada, dado que el elemento no existe, se creará y se establecerá en uno (1). El documento tendrá ahora este aspecto:

La segunda llamada pasa un uno negativo (-1), por lo que entonces el contador de le gusta se reducirá a cero (0). El documento JSON tendrá ahora este aspecto:

Conclusión

Desde la publicación en el blog de la vista previa para desarrolladores, el SDK .NET de Couchbase se ha actualizado a la versión 2.3.2 (en el momento de la publicación de este blog). Puedes echar un vistazo al trabajo que se ha hecho en la sección Notas de la versión 2.3.2.

Notas finales

La API de subdocumentos le ofrece la posibilidad de interactuar de forma más detallada con los documentos. Puede modificar y recuperar sólo las partes que necesite.

Deje un comentario a continuación, Háblame en Twittero envíeme un correo electrónico (matthew.groves AT couchbase DOT com) si tiene alguna pregunta o comentario.

Autor

Publicado por Matthew Groves

A Matthew D. Groves le encanta programar. No importa si se trata de C#, jQuery o PHP: enviará pull requests para cualquier cosa. Lleva codificando profesionalmente desde que escribió una aplicación de punto de venta en QuickBASIC para la pizzería de sus padres, allá por los años noventa. Actualmente trabaja como Director de Marketing de Producto para Couchbase. Su tiempo libre lo pasa con su familia, viendo a los Reds y participando en la comunidad de desarrolladores. Es autor de AOP in .NET, Pro Microservices in .NET, autor de Pluralsight y MVP de Microsoft.

Dejar una respuesta