{"id":2192,"date":"2016-03-10T21:51:31","date_gmt":"2016-03-10T21:51:30","guid":{"rendered":"https:\/\/www.couchbase.com\/blog\/?p=2192"},"modified":"2025-10-09T07:10:18","modified_gmt":"2025-10-09T14:10:18","slug":"developer-preview-of-new-sub-document-api-included-w-2-2-6-release-of-couchbase-net-sdk","status":"publish","type":"post","link":"https:\/\/www.couchbase.com\/blog\/es\/developer-preview-of-new-sub-document-api-included-w-2-2-6-release-of-couchbase-net-sdk\/","title":{"rendered":"Vista previa para desarrolladores de la nueva API de subdocumentos incluida en la versi\u00f3n 2.2.6 del SDK .NET de Couchbase"},"content":{"rendered":"<p><strong>Nota: todos los ejemplos se pueden encontrar <a href=\"https:\/\/github.com\/couchbaselabs\/couchbase-net-examples\/tree\/master\/Src\/Couchbase.Examples.SubDocumentAPI\" target=\"_blank\" rel=\"noopener noreferrer\">aqu\u00ed<\/a>.<\/strong><\/p>\n<p>Hoy lanzamos una Developer Preview (DP) muy especial de una nueva funcionalidad de la pr\u00f3xima versi\u00f3n de Couchbase Server llamada <em>Subdocumento<\/em>junto con nuestro Couchbase Server .NET SDK 2.2.6 normal. La API Sub-documento es una nueva caracter\u00edstica de Couchbase Server que est\u00e1 disponible en la Developer Preview de Couchbase Server 4.5.<\/p>\n<p>Si recuerdas, en Couchbase todas las mutaciones de documentos son at\u00f3micas e involucran a todo el documento. Si s\u00f3lo quieres cambiar un \u00fanico campo y luego haces una actualizaci\u00f3n, todo el documento en el servidor Couchbase es copiado por la nueva revisi\u00f3n. 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\u00f3n mejor y m\u00e1s eficaz ser\u00eda enviar s\u00f3lo 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\u00f3lo se env\u00eda la porci\u00f3n del documento que ha sido modificada. <i>ruta<\/i>\u00a0del fragmento que se va a mutar se env\u00eda por cable y s\u00f3lo se modifica esa parte del documento.<\/p>\n<p>La API admite varias operaciones diferentes, desde mutaciones en elementos anidados individuales o <em>sub-<\/em>a modificaciones de matrices y diccionarios. Tambi\u00e9n se admiten operaciones de contador, as\u00ed como operaciones de recuperaci\u00f3n de fragmentos JSON incrustados.<\/p>\n<p>La API se expone a trav\u00e9s de una interfaz fluida que permite a\u00f1adir m\u00faltiples operaciones y luego ejecutarlas contra el documento de forma at\u00f3mica. Existen dos \"constructores\" diferentes: un constructor para operaciones de mutaci\u00f3n y un constructor para lecturas o \"b\u00fasquedas\" y para comprobar si un elemento existe en una ruta determinada.<\/p>\n<h2 id=\"important-use-sub-document-api-dp-at-you-own-risk-\">IMPORTANTE: \u00a1\u00a1\u00a1La API de subdocumentos es una versi\u00f3n preliminar para desarrolladores!!!<\/h2>\n<p>Tenga en cuenta que se trata de una primera versi\u00f3n de la API de subdocumentos y que no se ha sometido a las comprobaciones y balances habituales a los que se someten las API antes de su publicaci\u00f3n. Adem\u00e1s, en funci\u00f3n de los comentarios de los usuarios, las interfaces p\u00fablicas pueden cambiar en versiones posteriores, por lo que no se recomienda utilizar la API de subdocumentos en producci\u00f3n... todav\u00eda. <strong><em>No obstante, el resto de la versi\u00f3n 2.2.6 ha sido probado y est\u00e1 listo para su uso en producci\u00f3n.<\/em><\/strong><\/p>\n<h3 id=\"prerequisite-couchbase-server-4-5-0-developer-preview\">Requisito previo: Couchbase Server 4.5.0 Developer Preview<\/h3>\n<p>Para poder seguir los ejemplos que se presentan a continuaci\u00f3n, deber\u00e1 descargar e instalar <a href=\"https:\/\/www.couchbase.com\/blog\/es\/\">Vista previa para desarrolladores de Couchbase Server 4.5<\/a>. \u00a1Vamos, hazlo ya!<\/p>\n<h2 id=\"sub-document-api-dp-overview\">Subdocumento API DP Descripci\u00f3n general<\/h2>\n<p>En los siguientes ejemplos se utilizar\u00e1 un documento con el id \"cachorro\" y tendr\u00e1 el siguiente aspecto:<\/p>\n<pre><code>  {\r\n  \"type\": \"dog\",\r\n  \"breed\": \"Pitbull\/Chihuahua\",\r\n  \"name\": \"Puppy\",\r\n  \"toys\": [\r\n    \"squeaker\",\r\n    \"ball\",\r\n    \"shoe\"\r\n  ],\r\n  \"owner\": {\r\n    \"type\": \"servant\",\r\n    \"name\": \"Don Knotts\",\r\n    \"age\": 63\r\n  },\r\n  \"attributes\": {\r\n    \"fleas\": true,\r\n    \"color\": \"white\",\r\n    \"eyeColor\": \"brown\",\r\n    \"age\": 5,\r\n    \"dirty\": true,\r\n    \"sex\": \"female\"\r\n  }\r\n}\r\n<\/code><\/pre>\n<p>Todos los ejemplos est\u00e1n disponibles en <a href=\"https:\/\/github.com\/couchbaselabs\/couchbase-net-examples\">Github <\/a>para que puedas clonar el proyecto y jugar con la API.<\/p>\n<h3 id=\"mutateinbuilder-and-lookupinbuilder\">MutateInBuilder y LookupInBuilder<\/h3>\n<p>Como se ha mencionado anteriormente, la API de subdocumentos ofrece dos nuevos tipos que utilizan un patr\u00f3n constructor a trav\u00e9s de una interfaz fluida para encadenar varias operaciones en un documento. Ambos objetos se crean llamando a <code>MutateIn<\/code> o <code>B\u00fasquedaEn<\/code> en un <code>CouchbaseBucket<\/code> e introduciendo la clave o id del documento con el que se est\u00e1 trabajando:<\/p>\n<pre><code>\/\/Initialize the cluster helper with the default settings - i.e. localhost\r\nClusterHelper.Initialize();\r\nvar bucket = ClusterHelper.GetBucket(\"default\");\r\n\r\n\/\/create a mutation builder for the document \"thekey\"\r\nvar mutate = bucket.MutateIn(\"thekey\");\r\n\r\n\/\/create a lookup builder for the document \"thekey2\"\r\nvar lookup = bucket.LookupIn(\"thekey2\");\r\n\r\nClusterHelper.Close();\r\n<\/code><\/pre>\n<p>Una vez que tenga el objeto constructor, puede encadenar una serie de operaciones para ejecutarlas contra el documento, por ejemplo:<\/p>\n<pre><code>var builder = bucket.LookupIn(id).\r\n            Get(\"type\").\r\n            Get(\"name\").\r\n            Get(\"owner\").\r\n            Exists(\"notfound\");\r\n<\/code><\/pre>\n<p>A continuaci\u00f3n, puede enviar todas las operaciones al servidor en un \u00fanico lote:<\/p>\n<pre><code>var fragment = builder.Execute();\r\n<\/code><\/pre>\n<p>Y, a continuaci\u00f3n, compruebe el resultado de una operaci\u00f3n para la ruta <code>tipo<\/code>:<\/p>\n<pre><code>if (fragment.OpStatus(\"type\") == ResponseStatus.Success)\r\n{\r\n    string format = \"Path='{0}' Value='{1}'\";\r\n    Console.WriteLine(format, \"type\", fragment.Content(\"type\"));\r\n}\r\n<\/code><\/pre>\n<p>El IDocumentFragment<\/p>\n<table>\n<thead>\n<tr>\n<th>Nombre<\/th>\n<th>Descripci\u00f3n<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Contenido(...)<\/td>\n<td>Obtiene el contenido de una ruta o \u00edndice dados.<\/td>\n<\/tr>\n<tr>\n<td>Existe(...)<\/td>\n<td>Devuelve true si hay un resultado para una ruta o \u00edndice dados.<\/td>\n<\/tr>\n<tr>\n<td>Contar()<\/td>\n<td>El recuento de las operaciones en curso mantenidas por el constructor.<\/td>\n<\/tr>\n<tr>\n<td>OpStatus(...)<\/td>\n<td>En <code>ResponseStatus<\/code> de una operaci\u00f3n en un \u00edndice o ruta determinados.<\/td>\n<\/tr>\n<tr>\n<td>Estado<\/td>\n<td>En <code>ResponseStatus<\/code> para toda la operaci\u00f3n m\u00faltiple.<\/td>\n<\/tr>\n<tr>\n<td>\u00c9xito<\/td>\n<td>Verdadero si la operaci\u00f3n m\u00faltiple completa tiene \u00e9xito.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Adem\u00e1s de estas propiedades o m\u00e9todos, existen todas las dem\u00e1s propiedades heredadas de <code>OperationResult<\/code> que es la respuesta est\u00e1ndar de una operaci\u00f3n K\/V: Upsert, Remove, Replace, etc.<\/p>\n<h3 id=\"error-handling\">Tratamiento de errores<\/h3>\n<p>Al enviar m\u00faltiples mutaciones, si una de ellas falla, falla toda la solicitud multioperaci\u00f3n, lo que permite una sem\u00e1ntica transaccional de todo o nada al realizar mutaciones dentro de un mismo documento. Cuando se env\u00edan m\u00faltiples b\u00fasquedas, algunas operaciones pueden tener \u00e9xito y otras pueden fallar, intentando el servidor devolver tantos elementos como se hayan solicitado. Si las operaciones fallan, la propiedad Status contendr\u00e1 una respuesta de error de nivel superior, como por ejemplo <code>SubDocMultiPathFailure,<\/code>\u00a0que es una indicaci\u00f3n para profundizar en los resultados de la operaci\u00f3n para obtener el error espec\u00edfico. Puede hacerlo iterando llamando al m\u00e9todo OpStatus y pasando el \u00edndice o la ruta:<\/p>\n<pre><code>var builder = bucket.LookupIn(id).\r\n            Get(\"type\").\r\n            Get(\"somepaththatdoesntexist\").\r\n            Get(\"owner\");\r\n\r\nvar fragment = builder.Execute();\r\nConsole.WriteLine(\"Generic error: {0}{1}Specific Error: {2}\", \r\n    fragment.Status, Environment.NewLine, fragment.OpStatus(1));\r\n\r\nConsole.WriteLine(\"Generic error: {0}{1}Specific Error: {2}\",\r\n    fragment.Status, Environment.NewLine, fragment.OpStatus(\"somepaththatdoesntexist\"));\r\n<\/code><\/pre>\n<p>En este caso, como la ruta no exist\u00eda dentro del documento, el error espec\u00edfico devuelto fue <code>SubDocPathNotFound<\/code>. Hay muchas combinaciones diferentes de errores dependiendo del tipo de constructor y la condici\u00f3n del error - esta es una breve introducci\u00f3n y deber\u00eda ser adecuada para empezar con la API.<\/p>\n<h2 id=\"lookupinbuilder-examples\">Ejemplos de LookupInBuilder<\/h2>\n<p>LookUpInBuilder admite dos operaciones: buscar un valor por ruta y comprobar la existencia de un valor en una ruta determinada.<\/p>\n<h3 id=\"get-\">Cons\u00edguelo:<\/h3>\n<p>Busquemos el <code>propietario<\/code> fragmento por <code>ruta<\/code>:<\/p>\n<pre><code>var builder = bucket.LookupIn(id).\r\n            Get(\"owner\").\r\n            Execute();\r\n\r\nvar owner = builder.Content(\"owner\");\r\n<\/code><\/pre>\n<p>La salida es:<\/p>\n<pre><code>{\r\n    \"type\": \"servant\",\r\n    \"name\": \"Don Knotts\",\r\n    \"age\": 63\r\n}\r\n<\/code><\/pre>\n<h3 id=\"exist-\">Existe:<\/h3>\n<p>Comprobemos si el <code>propietario<\/code> existe una ruta:<\/p>\n<pre><code>var builder = bucket.LookupIn(id).\r\n            Exists(\"owner\").\r\n            Execute();\r\n\r\nvar found = builder.Content(\"owner\");\r\n<\/code><\/pre>\n<p>El resultado es <code>verdadero<\/code>el camino <code>propietario<\/code> existe efectivamente en el documento.<\/p>\n<h2 id=\"mutateinbuilder\">MutateInBuilder<\/h2>\n<p>MutateInBuilder ofrece una serie de m\u00e9todos que permiten realizar mutaciones en valores escalares, diccionarios y matrices, as\u00ed como operaciones de contador at\u00f3mico.<\/p>\n<h3 id=\"insert-\">Insertar:<\/h3>\n<p>Insertar a\u00f1ade un valor a un diccionario permitiendo opcionalmente que se a\u00f1ada el elemento que lo contiene (el propio diccionario):<\/p>\n<pre><code>var builder = bucket.MutateIn(id).\r\n            Insert(\"attributes.hairLength\", \"short\").\r\n            Execute();\r\n<\/code><\/pre>\n<p>El diccionario de atributos del documento tendr\u00e1 ahora este aspecto:<\/p>\n<pre><code>...\r\n\"attributes\": \r\n{\r\n    \"fleas\": true,\r\n    \"color\": \"white\",\r\n    \"eyeColor\": \"brown\",\r\n    \"age\": 5,\r\n    \"dirty\": true,\r\n    \"sex\": \"female\",\r\n    \"hairLength\": \"short\"\r\n}\r\n...\r\n<\/code><\/pre>\n<p>Ahora bien, si el elemento padre no existe, la funci\u00f3n <code>crearPadres<\/code> para crear el elemento padre. Esto es true por defecto, as\u00ed que no tienes que hacer nada - pasa false si quieres fallar si el elemento padre no existe:<\/p>\n<pre><code>var builder = bucket.MutateIn(id).\r\n            Insert(\"anewattribute.withakey\", \"somevalue\").\r\n            Execute();\r\n<\/code><\/pre>\n<p>Esto crear\u00e1 el nuevo atributo llamado <code>unnuevoatributo<\/code> en el documento y a\u00f1adir una \u00fanica clave llamada <code>conakey<\/code> con un valor de <code>alg\u00fan valor<\/code>.<\/p>\n<pre><code>...\r\n\"anewattribute\": \r\n{\r\n    \"withakey\": \"somevalue\"\r\n}\r\n...\r\n<\/code><\/pre>\n<p>Ahora, si pasamos <code>falso<\/code> para <code>crearPadres<\/code> y el atributo padre no existiera, la mutaci\u00f3n m\u00faltiple fallar\u00eda con un estado de respuesta de nivel superior de <code>SubDocMultiPathFailure<\/code> y el error espec\u00edfico ser\u00eda <code>SubDocPathNotFound<\/code>.<\/p>\n<h3 id=\"upsert\">Upsert<\/h3>\n<p>Upsert a\u00f1adir\u00e1 o sustituir\u00e1 una entrada del diccionario existente. El uso es exactamente el mismo que <code>Inserte<\/code> con la excepci\u00f3n de que el nombre del m\u00e9todo es <code>Upsert<\/code>.<\/p>\n<h3 id=\"remove\">Eliminar<\/h3>\n<p><code>Eliminar<\/code> eliminar\u00e1 un elemento en una ruta dada. Como ejemplo, eliminaremos el nombre del propietario del documento anterior:<\/p>\n<pre><code> var fragment = bucket.MutateIn(id).\r\n            Remove(\"owner.name\").\r\n            Execute();\r\n<\/code><\/pre>\n<p>Y el documento despu\u00e9s de llamado <code>Eliminar<\/code>:<\/p>\n<pre><code>...\r\n\"owner\": \r\n{\r\n    \"type\": \"servant\",\r\n    \"age\": 63\r\n},\r\n...\r\n<\/code><\/pre>\n<h3 id=\"replace\">Sustituir<\/h3>\n<p>Reemplazar intercambiar\u00e1 el valor del elemento en una ruta dada, fallando si la ruta no existe:<\/p>\n<pre><code>var fragment = bucket.MutateIn(id).\r\n            Replace(\"owner\", new { CatLover=true, CatName=\"celia\"}).\r\n            Execute();\r\n<\/code><\/pre>\n<p>El documento tendr\u00e1 ahora un valor diferente para \"propietario\":<\/p>\n<pre><code>...\r\n\"owner\": \r\n{\r\n    \"catLover\": true,\r\n    \"catName\": \"celia\"\r\n},\r\n...\r\n<\/code><\/pre>\n<h3 id=\"pushback\">PushBack<\/h3>\n<p>A\u00f1ade un valor a la parte posterior de un array a\u00f1adiendo opcionalmente el elemento padre (el propio elemento del array) si no existe.<\/p>\n<pre><code>var fragment = bucket.MutateIn(id).\r\n            PushBack(path, value, false).\r\n            Execute();\r\n<\/code><\/pre>\n<p>En <code>juguetes<\/code> del documento tiene ahora el valor \"zapatilla\" en el \u00faltimo ordinal:<\/p>\n<pre><code>...\r\n\"toys\": \r\n[ \r\n    \"squeaker\", \r\n    \"ball\", \r\n    \"shoe\", \r\n    \"slipper\"\r\n],\r\n...\r\n<\/code><\/pre>\n<h3 id=\"pushfront\">PushFront<\/h3>\n<p>A\u00f1ade un valor al principio de un array a\u00f1adiendo opcionalmente el elemento padre (el propio array) si no existe:<\/p>\n<pre><code>var fragment = bucket.MutateIn(id).\r\n            PushFront(path, value, false).\r\n            Execute();\r\n<\/code><\/pre>\n<p>En <code>juguetes<\/code> tiene ahora el valor \"zapatilla\" en su primer ordinal:<\/p>\n<pre><code>...\r\n\"toys\": \r\n[\r\n    \"slipper\",\r\n    \"squeaker\",\r\n    \"ball\",\r\n    \"shoe\"\r\n],\r\n...\r\n<\/code><\/pre>\n<h3 id=\"arrayinsert\">ArrayInsert<\/h3>\n<p>Inserta un valor en un array en un \u00edndice dado:<\/p>\n<pre><code> var fragment = bucket.MutateIn(id).\r\n            ArrayInsert(\"toys[2]\", \"slipper\").\r\n            Execute();\r\n<\/code><\/pre>\n<p>En <code>juguetes<\/code> tiene ahora el valor \"zapatilla\" en su ordinal 3 (\u00edndice 2):<\/p>\n<pre><code>\"toys\": \r\n[\r\n    \"squeaker\",\r\n    \"ball\",\r\n    \"slipper\",\r\n    \"shoe\"\r\n ],\r\n<\/code><\/pre>\n<h3 id=\"addunique\">A\u00f1adirUnico<\/h3>\n<p>Inserta un valor en un array, fallando si existe (el valor debe ser \u00fanico dentro del array):<\/p>\n<pre><code> var fragment = bucket.MutateIn(id).\r\n            AddUnique(\"toys\", \"shoe\").\r\n            Execute();\r\n<\/code><\/pre>\n<p>Dado que el valor \"shoe\" ya existe en el documento original de <code>juguetes<\/code> esto fallar\u00e1 con el siguiente estado:<\/p>\n<pre><code>SubDocPathExists\r\n<\/code><\/pre>\n<p>Tenga en cuenta que este m\u00e9todo s\u00f3lo permite insertar primitivas JSON: cadenas, n\u00fameros y valores especiales para true, false o null. La raz\u00f3n es que no hay forma de comparar la unicidad sin descender a cada objeto JSON y comparar los elementos elemento por elemento.<\/p>\n<h3 id=\"counter\">Contador<\/h3>\n<p>A\u00f1ade el delta especificado a un valor existente, creando el elemento si no existe y poniendo por defecto el valor y el delta a 0. Si el delta es negativo, el valor del elemento se reducir\u00e1 en el delta dado.<\/p>\n<pre><code>var fragment = bucket.MutateIn(id).\r\n            Counter(\"likes\", 1).\r\n            Execute();\r\n<\/code><\/pre>\n<p>Dado que el elemento no existe, se crear\u00e1 y se establecer\u00e1 en uno (1). El documento tendr\u00e1 ahora este aspecto:<\/p>\n<pre><code>...\r\n    ],\r\n    \"likes\": 1\r\n}\r\n<\/code><\/pre>\n<p>Si pasamos un uno negativo (-1), entonces el contador de <code>le gusta<\/code> volver\u00e1 a cero (0):<\/p>\n<pre><code>var fragment = bucket.MutateIn(id).\r\n            Counter(\"likes\", -1).\r\n            Execute();\r\n<\/code><\/pre>\n<p>Y el documento JSON tendr\u00e1 ahora este aspecto:<\/p>\n<pre><code>...\r\n    ],\r\n    \"likes\": 0\r\n}\r\n<\/code><\/pre>\n<h2 id=\"release-notes-for-v2-2-6\">Notas de la versi\u00f3n 2.2.6<\/h2>\n<h3>Error<\/h3>\n<ul>\n<li>[<a href=\"https:\/\/issues.couchbase.com\/browse\/NCBC-981\">NCBC-981<\/a>] - Cuando se define FQDN para la instancia de Couchbase, SSL falla.<\/li>\n<li>[<a href=\"https:\/\/issues.couchbase.com\/browse\/NCBC-1074\">NCBC-1074<\/a>] - La solicitud de vista se bloquea indefinidamente si se espera de forma sincr\u00f3nica<\/li>\n<li>[<a href=\"https:\/\/issues.couchbase.com\/browse\/NCBC-1083\">NCBC-1083<\/a>] - PoolConfiguration sigue utilizando la configuraci\u00f3n predeterminada cuando se anula<\/li>\n<li>[<a href=\"https:\/\/issues.couchbase.com\/browse\/NCBC-1084\">NCBC-1084<\/a>] - ConfigurationSection ignora UseSsl<\/li>\n<li>[<a href=\"https:\/\/issues.couchbase.com\/browse\/NCBC-1086\">NCBC-1086<\/a>] - GetAndLock no devuelve el estado Bloqueado pero se agota el tiempo de espera cuando el documento est\u00e1 bloqueado<\/li>\n<\/ul>\n<h3>Mejora<\/h3>\n<ul>\n<li>[<a href=\"https:\/\/issues.couchbase.com\/browse\/NCBC-1070\">NCBC-1070<\/a>] - Hacer que QueryRequest no dependa de JSON.NET<\/li>\n<li>[<a href=\"https:\/\/issues.couchbase.com\/browse\/NCBC-1082\">NCBC-1082<\/a>] - A\u00f1adir soporte para sortCount en QueryResult.Metrics<\/li>\n<li>[<a href=\"https:\/\/issues.couchbase.com\/browse\/NCBC-1085\">NCBC-1085<\/a>] - Retrollamada de espera para que no se bloquee el subproceso de ejecuci\u00f3n<\/li>\n<li>[<a href=\"https:\/\/issues.couchbase.com\/browse\/NCBC-1090\">NCBC-1090<\/a>] - Fix \" No se puede esperar en el cuerpo de una cl\u00e1usula catch\" en SSL IO<\/li>\n<\/ul>\n<h3>Nueva funci\u00f3n<\/h3>\n<ul>\n<li>[<a href=\"https:\/\/issues.couchbase.com\/browse\/NCBC-998\">NCBC-998<\/a>] - Incluir soporte para Subdocument API - Parte 1 Multi-comandos DP<\/li>\n<\/ul>\n<h2 id=\"how-to-get-v2-2-6\">C\u00f3mo conseguir la v2.2.6<\/h2>\n<ul>\n<li>Descargar los binarios <a href=\"https:\/\/s3.amazonaws.com\/packages.couchbase.com\/clients\/net\/2.2\/Couchbase-Net-Client-2.2.6.zip\" target=\"_blank\" rel=\"noopener noreferrer\">aqu\u00ed.<\/a><\/li>\n<li>El paquete NuGet se encuentra en <a href=\"https:\/\/www.nuget.org\/packages\/CouchbaseNetClient\/2.2.6\" target=\"_blank\" rel=\"noopener noreferrer\">aqu\u00ed<\/a>.<\/li>\n<li>El repositorio de Github es <a href=\"https:\/\/github.com\/couchbase\/couchbase-net-client\/tree\/2.2.6\">aqu\u00ed<\/a>.<\/li>\n<\/ul>","protected":false},"excerpt":{"rendered":"<p>Note: all examples can be found here. Today we are releasing a very special Developer Preview (DP) of a new feature in the upcoming release of Couchbase Server called Sub-document, along with our normal Couchbase Server .NET SDK 2.2.6! The [&hellip;]<\/p>","protected":false},"author":21,"featured_media":13873,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[1811,2201],"tags":[1606,1586],"ppma_author":[8970],"class_list":["post-2192","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-dotnet","category-tools-sdks","tag-sub-document","tag-subdocument"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v26.2 (Yoast SEO v26.2) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Sub-document API included Couchbase .NET SDK<\/title>\n<meta name=\"description\" content=\"Check out the Sub-document API is a new feature of Couchbase Server that is available in the Developer Preview of Couchbase Server 4.5.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.couchbase.com\/blog\/es\/developer-preview-of-new-sub-document-api-included-w-2-2-6-release-of-couchbase-net-sdk\/\" \/>\n<meta property=\"og:locale\" content=\"es_MX\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Developer Preview of new Sub-document API included w\/2.2.6 release of Couchbase .NET SDK\" \/>\n<meta property=\"og:description\" content=\"Check out the Sub-document API is a new feature of Couchbase Server that is available in the Developer Preview of Couchbase Server 4.5.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.couchbase.com\/blog\/es\/developer-preview-of-new-sub-document-api-included-w-2-2-6-release-of-couchbase-net-sdk\/\" \/>\n<meta property=\"og:site_name\" content=\"The Couchbase Blog\" \/>\n<meta property=\"article:published_time\" content=\"2016-03-10T21:51:30+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-10-09T14:10:18+00:00\" \/>\n<meta name=\"author\" content=\"Jeff Morris, Senior Software Engineer, Couchbase\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@jeffrysmorris\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Jeff Morris, Senior Software Engineer, Couchbase\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"7 minutos\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/developer-preview-of-new-sub-document-api-included-w-2-2-6-release-of-couchbase-net-sdk\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/developer-preview-of-new-sub-document-api-included-w-2-2-6-release-of-couchbase-net-sdk\/\"},\"author\":{\"name\":\"Jeff Morris, Senior Software Engineer, Couchbase\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/b678bdd9f7b21a33d43ea965865a3341\"},\"headline\":\"Developer Preview of new Sub-document API included w\/2.2.6 release of Couchbase .NET SDK\",\"datePublished\":\"2016-03-10T21:51:30+00:00\",\"dateModified\":\"2025-10-09T14:10:18+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/developer-preview-of-new-sub-document-api-included-w-2-2-6-release-of-couchbase-net-sdk\/\"},\"wordCount\":1474,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/developer-preview-of-new-sub-document-api-included-w-2-2-6-release-of-couchbase-net-sdk\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"keywords\":[\"sub-document\",\"subdocument\"],\"articleSection\":[\".NET\",\"Tools &amp; SDKs\"],\"inLanguage\":\"es\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/developer-preview-of-new-sub-document-api-included-w-2-2-6-release-of-couchbase-net-sdk\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/developer-preview-of-new-sub-document-api-included-w-2-2-6-release-of-couchbase-net-sdk\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/developer-preview-of-new-sub-document-api-included-w-2-2-6-release-of-couchbase-net-sdk\/\",\"name\":\"Sub-document API included Couchbase .NET SDK\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/developer-preview-of-new-sub-document-api-included-w-2-2-6-release-of-couchbase-net-sdk\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/developer-preview-of-new-sub-document-api-included-w-2-2-6-release-of-couchbase-net-sdk\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"datePublished\":\"2016-03-10T21:51:30+00:00\",\"dateModified\":\"2025-10-09T14:10:18+00:00\",\"description\":\"Check out the Sub-document API is a new feature of Couchbase Server that is available in the Developer Preview of Couchbase Server 4.5.\",\"breadcrumb\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/developer-preview-of-new-sub-document-api-included-w-2-2-6-release-of-couchbase-net-sdk\/#breadcrumb\"},\"inLanguage\":\"es\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/developer-preview-of-new-sub-document-api-included-w-2-2-6-release-of-couchbase-net-sdk\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/developer-preview-of-new-sub-document-api-included-w-2-2-6-release-of-couchbase-net-sdk\/#primaryimage\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"width\":1800,\"height\":630},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/developer-preview-of-new-sub-document-api-included-w-2-2-6-release-of-couchbase-net-sdk\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.couchbase.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Developer Preview of new Sub-document API included w\/2.2.6 release of Couchbase .NET SDK\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\",\"url\":\"https:\/\/www.couchbase.com\/blog\/\",\"name\":\"The Couchbase Blog\",\"description\":\"Couchbase, the NoSQL Database\",\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.couchbase.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"es\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\",\"name\":\"The Couchbase Blog\",\"url\":\"https:\/\/www.couchbase.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png\",\"width\":218,\"height\":34,\"caption\":\"The Couchbase Blog\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/b678bdd9f7b21a33d43ea965865a3341\",\"name\":\"Jeff Morris, Senior Software Engineer, Couchbase\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/73188ee2831025d81740e12e1ed80812\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/5f910befdbd58de8bac85293df7f544680843061ecc921ba7d293d6d52076ab3?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/5f910befdbd58de8bac85293df7f544680843061ecc921ba7d293d6d52076ab3?s=96&d=mm&r=g\",\"caption\":\"Jeff Morris, Senior Software Engineer, Couchbase\"},\"description\":\"Jeff Morris is a Senior Software Engineer at Couchbase. Prior to joining Couchbase, Jeff spent six years at Source Interlink as an Enterprise Web Architect. Jeff is responsible for the development of Couchbase SDKs and how to integrate with N1QL (query language).\",\"sameAs\":[\"https:\/\/x.com\/jeffrysmorris\"],\"url\":\"https:\/\/www.couchbase.com\/blog\/es\/author\/jeff-morris\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Sub-document API included Couchbase .NET SDK","description":"Echa un vistazo a la API Sub-documento es una nueva caracter\u00edstica de Couchbase Server que est\u00e1 disponible en la Developer Preview de Couchbase Server 4.5.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.couchbase.com\/blog\/es\/developer-preview-of-new-sub-document-api-included-w-2-2-6-release-of-couchbase-net-sdk\/","og_locale":"es_MX","og_type":"article","og_title":"Developer Preview of new Sub-document API included w\/2.2.6 release of Couchbase .NET SDK","og_description":"Check out the Sub-document API is a new feature of Couchbase Server that is available in the Developer Preview of Couchbase Server 4.5.","og_url":"https:\/\/www.couchbase.com\/blog\/es\/developer-preview-of-new-sub-document-api-included-w-2-2-6-release-of-couchbase-net-sdk\/","og_site_name":"The Couchbase Blog","article_published_time":"2016-03-10T21:51:30+00:00","article_modified_time":"2025-10-09T14:10:18+00:00","author":"Jeff Morris, Senior Software Engineer, Couchbase","twitter_card":"summary_large_image","twitter_creator":"@jeffrysmorris","twitter_misc":{"Written by":"Jeff Morris, Senior Software Engineer, Couchbase","Est. reading time":"7 minutos"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.couchbase.com\/blog\/developer-preview-of-new-sub-document-api-included-w-2-2-6-release-of-couchbase-net-sdk\/#article","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/developer-preview-of-new-sub-document-api-included-w-2-2-6-release-of-couchbase-net-sdk\/"},"author":{"name":"Jeff Morris, Senior Software Engineer, Couchbase","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/b678bdd9f7b21a33d43ea965865a3341"},"headline":"Developer Preview of new Sub-document API included w\/2.2.6 release of Couchbase .NET SDK","datePublished":"2016-03-10T21:51:30+00:00","dateModified":"2025-10-09T14:10:18+00:00","mainEntityOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/developer-preview-of-new-sub-document-api-included-w-2-2-6-release-of-couchbase-net-sdk\/"},"wordCount":1474,"commentCount":0,"publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/developer-preview-of-new-sub-document-api-included-w-2-2-6-release-of-couchbase-net-sdk\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","keywords":["sub-document","subdocument"],"articleSection":[".NET","Tools &amp; SDKs"],"inLanguage":"es","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.couchbase.com\/blog\/developer-preview-of-new-sub-document-api-included-w-2-2-6-release-of-couchbase-net-sdk\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.couchbase.com\/blog\/developer-preview-of-new-sub-document-api-included-w-2-2-6-release-of-couchbase-net-sdk\/","url":"https:\/\/www.couchbase.com\/blog\/developer-preview-of-new-sub-document-api-included-w-2-2-6-release-of-couchbase-net-sdk\/","name":"Sub-document API included Couchbase .NET SDK","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/developer-preview-of-new-sub-document-api-included-w-2-2-6-release-of-couchbase-net-sdk\/#primaryimage"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/developer-preview-of-new-sub-document-api-included-w-2-2-6-release-of-couchbase-net-sdk\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","datePublished":"2016-03-10T21:51:30+00:00","dateModified":"2025-10-09T14:10:18+00:00","description":"Echa un vistazo a la API Sub-documento es una nueva caracter\u00edstica de Couchbase Server que est\u00e1 disponible en la Developer Preview de Couchbase Server 4.5.","breadcrumb":{"@id":"https:\/\/www.couchbase.com\/blog\/developer-preview-of-new-sub-document-api-included-w-2-2-6-release-of-couchbase-net-sdk\/#breadcrumb"},"inLanguage":"es","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.couchbase.com\/blog\/developer-preview-of-new-sub-document-api-included-w-2-2-6-release-of-couchbase-net-sdk\/"]}]},{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/www.couchbase.com\/blog\/developer-preview-of-new-sub-document-api-included-w-2-2-6-release-of-couchbase-net-sdk\/#primaryimage","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","width":1800,"height":630},{"@type":"BreadcrumbList","@id":"https:\/\/www.couchbase.com\/blog\/developer-preview-of-new-sub-document-api-included-w-2-2-6-release-of-couchbase-net-sdk\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.couchbase.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Developer Preview of new Sub-document API included w\/2.2.6 release of Couchbase .NET SDK"}]},{"@type":"WebSite","@id":"https:\/\/www.couchbase.com\/blog\/#website","url":"https:\/\/www.couchbase.com\/blog\/","name":"El blog de Couchbase","description":"Couchbase, la base de datos NoSQL","publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.couchbase.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"es"},{"@type":"Organization","@id":"https:\/\/www.couchbase.com\/blog\/#organization","name":"El blog de Couchbase","url":"https:\/\/www.couchbase.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png","width":218,"height":34,"caption":"The Couchbase Blog"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/b678bdd9f7b21a33d43ea965865a3341","name":"Jeff Morris, Ingeniero Superior de Software, Couchbase","image":{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/73188ee2831025d81740e12e1ed80812","url":"https:\/\/secure.gravatar.com\/avatar\/5f910befdbd58de8bac85293df7f544680843061ecc921ba7d293d6d52076ab3?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/5f910befdbd58de8bac85293df7f544680843061ecc921ba7d293d6d52076ab3?s=96&d=mm&r=g","caption":"Jeff Morris, Senior Software Engineer, Couchbase"},"description":"Jeff Morris es Ingeniero de Software Senior en Couchbase. Antes de unirse a Couchbase, Jeff pas\u00f3 seis a\u00f1os en Source Interlink como Arquitecto Web Empresarial. Jeff es responsable del desarrollo de los SDK de Couchbase y de c\u00f3mo integrarse con N1QL (lenguaje de consulta).","sameAs":["https:\/\/x.com\/jeffrysmorris"],"url":"https:\/\/www.couchbase.com\/blog\/es\/author\/jeff-morris\/"}]}},"authors":[{"term_id":8970,"user_id":21,"is_guest":0,"slug":"jeff-morris","display_name":"Jeff Morris, Senior Software Engineer, Couchbase","avatar_url":"https:\/\/secure.gravatar.com\/avatar\/5f910befdbd58de8bac85293df7f544680843061ecc921ba7d293d6d52076ab3?s=96&d=mm&r=g","author_category":"","last_name":"Jeff Morris, Senior Software Engineer, Couchbase","first_name":"Jeff","job_title":"","user_url":"","description":"Jeff Morris es Ingeniero de Software Senior en Couchbase. Antes de unirse a Couchbase, Jeff pas\u00f3 seis a\u00f1os en Source Interlink como Arquitecto Web Empresarial. Jeff es responsable del desarrollo de los SDK de Couchbase y de c\u00f3mo integrarse con N1QL (lenguaje de consulta)."}],"_links":{"self":[{"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/posts\/2192","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/users\/21"}],"replies":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/comments?post=2192"}],"version-history":[{"count":0,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/posts\/2192\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/media\/13873"}],"wp:attachment":[{"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/media?parent=2192"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/categories?post=2192"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/tags?post=2192"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/ppma_author?post=2192"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}