Advanced Bucket Accessors en Couchbase hace posible acceder a funcionalidades avanzadas de almacenes de valor-clave (KV) usando los siguientes operadores incorporados.
Utilizan los mismos bucket bindings definidos en el handler que los Basic Bucket Accessors, pero exponen un conjunto más rico de opciones y operadores que se pueden utilizar para:
- Fijar o recuperar vencimientos
- Resolver condiciones de carrera mediante CAS
- Manipular elementos KV calientes bajo alta contención
Tenga en cuenta que Accesorios básicos para cubos son mucho más fáciles de usar, tienen una API trivial, y también son un poco más rápidos que los correspondientes Advanced Bucket Accessors.
En Couchbase Server 6.6.1 se han añadido los siguientes Advanced Bucket Accessors:
Estos siete nuevos bucket accessors permiten utilizar y aprovechar CAS directamente para gestionar la contención y/o establecer la caducidad de un documento (o TTL) en el servicio de datos (o KV) a través de Eventos además de realizar operaciones de contador atómico distribuido.
Por ejemplo, en lugar de confiar ciegamente en los accesores de cubo básicos para una operación similar a upsert src_bkt[id_str] = some_doc
En el caso de los accesos avanzados, los accesos avanzados le permiten resolver la contención (o posible contención) en claves que tienen mutaciones concurrentes de diferentes fuentes con lógica basada en JavaScript en su función de eventos.
-
- Si el documento no existe, puede utilizar
couchbase.insert(src_bkt, {"id: id_str}, some_doc)
y comprobar si el valor devuelto es correcto - Si el documento existe, puede utilizar
couchbase.replace(src_bkt, {"id: id_str, "cas": current_cas}, some_doc)
y comprueba si el valor de retorno es correcto o no.
- Si el documento no existe, puede utilizar
Para ver ejemplos completos que incluyan JavaScript, mutaciones de entrada, mutaciones de salida y/o mensajes de registro para cada accesorio de cubo avanzado, consulte Scriptlets: Manejadores de accesos avanzados en la sección de ejemplos de la documentación.
GET avanzado: resultado = couchbase.get(binding, meta)
Esta operación permite leer un documento junto con los metadatos del bucket y las operaciones posteriores para utilizar CAS o comprobar/modificar el fecha_de_vencimiento
.
En contraste con el accesorio de cubo básico GET
que simplemente expone un enlace o mapa JavaScript, var adoc = src_bkt[meta.id]
cuyo valor de retorno es el documento sin metadatos.
A continuación se muestra un ejemplo de la opción Avanzada GET
operación.
1 2 3 4 5 6 7 8 9 10 11 12 |
función OnUpdate(doc, meta) { registro('input doc ', doc); registro('input meta', meta); // puede ser el mismo o diferente var nueva_meta = {"id":"test_adv_get::1"}; var resultado = couchbase.consiga(src_bkt,nueva_meta); si (resultado.éxito) { registro(éxito adv. obtener: resultado,resultado); } si no { registro('fallo adv. get: id',nueva_meta.id,resultado,resultado); } } |
Algunos ejemplos de valores de retorno:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
{ "doc": { "id": 1, "tipo": "test_adv_get" }, "meta": { "id": "test_adv_get::1", "cas": "1610034762747412480", "tipo_datos": "json" }, "éxito": verdadero } { "doc": { "a": 1, "aleatorio": 0.09799092443129842 }, "meta": { "id": "test_adv_insert:1", "cas": "1610140272584884224", "fecha_expiración": "2021-01-08T21:12:12.000Z", "tipo_datos": "json" }, "éxito": verdadero } { "error": { "código": 272, "nombre": "LCB_KEY_ENOENT", "desc": "La clave del documento no existe en el servidor", "clave_no_encontrada": verdadero }, "éxito": falso } |
INSERT avanzado: resultado = couchbase.insert(binding, meta, doc)
Esta operación permite crear un nuevo documento en el bucket. Esta operación fallará si el documento con la clave especificada ya existe. Permite especificar un tiempo de expiración (o TTL) para el documento.
No existe una operación de acceso a cubos básicos análoga a la operación de acceso a cubos avanzados. INSERTAR
operación (como src_bkt[meta.id] = adoc
es más bien un upsert).
A continuación se muestra un ejemplo de la opción Avanzada INSERTAR
operación.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
función OnUpdate(doc, meta) { registro('input meta', meta); registro('input doc ', doc); // puede ser el mismo o diferente var nueva_meta = {"id":"test_adv_insert:1"}; // opcional establecer un vencimiento 60 segundos en el futuro // new_meta.expiry_date = new Date(Date.now() + 60 * 1000); var nuevo_documento = doc; nuevo_documento.al azar = Matemáticas.al azar(); var resultado = couchbase.insertar(src_bkt,nueva_meta,nuevo_documento); si (resultado.éxito) { registro('éxito adv. insertar: resultado',resultado); } si no { registro('fallo adv. insertar: id',nueva_meta.id,resultado,resultado); } } |
Algunos ejemplos de valores de retorno:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
{ "meta": { "id": "test_adv_insert:1", "cas": "1610041053310025728" }, "éxito": verdadero } { "error": { "código": 272, "nombre": "LCB_KEY_EEXISTS", "desc": "La clave del documento ya existe en el servidor"., "clave_ya_existe": verdadero }, "éxito": falso } |
UPSERT avanzado: resultado = couchbase.upsert(binding, meta, doc)
Esta operación permite actualizar un documento existente en el bucket o, en su defecto, crear un documento nuevo con la clave especificada. La operación no permite especificar CAS (se ignorará silenciosamente). También permite especificar un tiempo de expiración (o TTL) que se establecerá en el documento.
En contraste con el accesorio de cubo básico SET
que se limita a utilizar un mapa JavaScript expuesto definido mediante un alias de vinculación de bucket src_bkt[meta.id] = adoc
. Para la base SET
no hay valor de retorno (ni estado ni metadatos), por lo que no hay forma de comprobar el valor CAS.
A continuación se muestra un ejemplo de la opción Avanzada UPSERT
operación.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
función OnUpdate(doc, meta) { registro('input meta', meta); registro('input doc ', doc); // puede ser el mismo o diferente var nueva_meta = {"id":"test_adv_upsert:1"}; // CAS si se suministra será ignorado // opcional establecer un vencimiento 60 segundos en el futuro // new_meta.expiry_date = new Date(Date.now() + 60 * 1000); var nuevo_documento = doc; nuevo_documento.al azar = Matemáticas.al azar(); var resultado = couchbase.upsert(src_bkt,nueva_meta,nuevo_documento); si (resultado.éxito) { registro('éxito adv. upsert: resultado',resultado); } si no { registro('fallo adv. upsert: id',nueva_meta.id,resultado,resultado); } } |
Un ejemplo de valor de retorno:
1 2 3 4 5 6 7 |
{ "meta": { "id": "test_adv_upsert:1", "cas": "1610127444908376064" }, "éxito": verdadero } |
Sustitución avanzada: resultado = couchbase.replace(binding, meta, doc)
Esta operación sustituye un documento existente en el bucket. Esta operación fallará si el documento con la clave especificada no existe. Esta operación permite especificar un valor CAS que debe coincidir como condición previa antes de proceder con la operación. También permite especificar un tiempo de expiración (o TTL) que debe establecerse en el documento.
No existe una operación de acceso a cubos básicos análoga a la operación de acceso a cubos avanzados. SUSTITUIR
operación (como src_bkt[meta.id] = adoc
es más bien un upsert).
A continuación se muestra un ejemplo de la opción Avanzada SUSTITUIR
operación.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
función OnUpdate(doc, meta) { registro('input meta', meta); registro('input doc ', doc); var modo = 3; // 1-> no CA, 2-> desajuste en CA, 3-> buen CAS // Configuración, asegúrese de que tenemos nuestro documento para "reemplazar", ignorar cualquier error couchbase.insertar(src_bkt,{"id":"test_adv_replace:10"},{"a:": 1}); var nueva_meta; si (modo === 1) { // Si no pasamos CAS tendrá éxito nueva_meta = {"id":"test_adv_replace:10"}; // opcional establecer un vencimiento 60 segundos en el futuro // new_meta.expiry_date = new Date(Date.now() + 60 * 1000); } si (modo === 2) { // Si pasamos un CAS no coincidente fallará, así que prueba esto nueva_meta = {"id":"test_adv_replace:10", "cas":"1111111111111111111"}; } si (modo === 3) { // Si pasamos el CAS coincidente o actual tendrá éxito var tmp_r = couchbase.consiga(src_bkt,{"id":"test_adv_replace:10"}); si (tmp_r.éxito) { // Aquí usamos el CAS actual que acabamos de leer a través de couchbase.get(...) nueva_meta = {"id":"test_adv_replace:10", "cas": tmp_r.meta.cas}; } si no { registro('No se puede reemplazar la clave no existente que crearlo y volver a ejecutar',"test_adv_replace:10"); devolver; } } var nuevo_documento = doc; nuevo_documento.al azar = Matemáticas.al azar(); var resultado = couchbase.sustituir(src_bkt,nueva_meta,nuevo_documento); si (resultado.éxito) { registro(éxito adv. sustituir: resultado,resultado); } si no { registro('fallo adv. reemplazar: id',nueva_meta.id,resultado,resultado); } } |
Algunos ejemplos de valores de retorno:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
{ "meta": { "id": "test_adv_replace:10", "cas": "1610130177286144000" }, "éxito": verdadero } { "error": { "código": 272, "nombre": "LCB_KEY_EEXISTS", "desc": "La clave del documento existe con un valor CAS diferente al especificado", "cas_mismatch": verdadero }, "éxito": falso } |
Supresión avanzada: resultado = couchbase.delete(binding, meta)
Esta operación permite eliminar un documento del bucket especificado por key. Opcionalmente, se puede especificar un valor CAS que se cotejará como condición previa para proceder con la operación.
En contraste con el accesorio de cubo básico DEL
que simplemente utiliza un enlace o mapa JavaScript expuesto, delete src_bkt[meta.id]
donde no hay valor de retorno (ni estado ni metadatos).
A continuación se muestra un ejemplo de la opción Avanzada BORRAR
operación.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
función OnUpdate(doc, meta) { registro('input meta', meta); registro('input doc ', doc); var modo = 4; // 1-> no CA, 2-> falta de coincidencia en CA, 3-> buena CAS, 4-> no existe tal clave // Configuración, asegúrese de que tenemos nuestro doc a "eliminar", ignorar cualquier error couchbase.insertar(src_bkt,{"id":"test_adv_delete:10"},{"a:": 1}); var nueva_meta; si (modo === 1) { // Si no pasamos CAS tendrá éxito nueva_meta = {"id":"test_adv_delete:10"}; // opcional establecer un vencimiento 60 segundos en el futuro // new_meta.expiry_date = new Date(Date.now() + 60 * 1000); } si (modo === 2) { // Si pasamos un CAS no coincidente fallará, así que prueba esto nueva_meta = {"id":"test_adv_delete:10", "cas":"1111111111111111111"}; } si (modo === 3) { // Si pasamos el CAS coincidente o actual tendrá éxito var tmp_r = couchbase.consiga(src_bkt,{"id":"test_adv_delete:10"}); si (tmp_r.éxito) { // Aquí usamos el CAS actual que acabamos de leer a través de couchbase.get(...) nueva_meta = {"id":"test_adv_delete:10", "cas": tmp_r.meta.cas}; } si no { registro('No se puede eliminar la clave no existente que crearlo y volver a ejecutar',"test_adv_delete:10"); devolver; } } si (modo === 4) { // Eliminar para que tengamos: no hay tal clave borrar src_bkt["test_adv_delete:10"] nueva_meta = {"id":"test_adv_delete:10"}; } var resultado = couchbase.borrar(src_bkt,nueva_meta); si (resultado.éxito) { registro('éxito adv. suprimir: resultado',resultado); } si no { registro('fallo adv. borrar: id',nueva_meta.id,resultado,resultado); } } |
Algunos ejemplos de valores de retorno:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
{ "meta": { "id": "clave::10", "cas": "1609374065129816064" }, "éxito": verdadero } { "error": { "código": 272, "nombre": "LCB_KEY_EEXISTS", "desc": "La clave del documento existe con un valor CAS diferente al especificado", "cas_mismatch": verdadero }, "éxito": falso } { "error": { "código": 272, "nombre": "LCB_KEY_ENOENT", "desc": "La clave del documento no existe en el servidor", "clave_no_encontrada": verdadero }, "éxito": falso } |
INCREMENTO Avanzado: resultado = couchbase.increment(binding, meta)
Esta operación incrementa atómicamente el campo cuente
en el documento especificado. El documento debe tener la siguiente estructura:
1 |
{"contar": 23} // 23 es el valor actual del contador |
En incrementar
devuelve el valor posterior al incremento.
Si el documento de contador especificado no existe, se crea uno con cuente
como 0 y la estructura indicada anteriormente. Y así, el primer valor devuelto será 1.
Debido a las limitaciones de la API del motor KV, esta operación no puede manipular actualmente contadores de documentos completos.
No existe una operación de acceso a cubos básicos análoga a la operación de acceso a cubos avanzados. INCREMENTO
operación.
A continuación se muestra un ejemplo de la opción Avanzada INCREMENTO
operación.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
función OnUpdate(doc, meta) { registro('input meta', meta); registro('input doc ', doc); // si doc.count no existe se creará var ctr_meta = {"id": "mi_contador_atómico:1" }; var resultado = couchbase.incrementar(src_bkt,ctr_meta); si (resultado.éxito) { registro(éxito adv. incremento: resultado,resultado); } si no { registro('fallo adv. incremento: id',ctr_meta.id,resultado,resultado); } } |
Un valor de retorno de ejemplo, suponga que crea esto KEY "my_atomic_counter:1" DOC {"count": 23}
si se despliega la función Eventing anterior, el recuento se incrementará inmediatamente:
1 2 3 4 5 6 7 8 9 10 |
{ "doc": { "contar": 24 }, "meta": { "id": "clave::1", "cas": "1609374571840471040" }, "éxito": verdadero } |
DECREMENTO Avanzado: resultado = couchbase.decrement(binding, meta)
Esta operación decrementa atómicamente el campo cuente
en el documento especificado. El documento debe tener la siguiente estructura:
1 |
{"contar": 23} // 23 es el valor actual del contador |
En decremento
devuelve el valor posterior a la reducción.
Si el documento de contador especificado no existe, se crea uno con la opción cuente
como 0 y la estructura indicada anteriormente. Como resultado, el primer valor devuelto será -1.
Debido a las limitaciones de la API del motor KV, esta operación no puede manipular actualmente contadores de documentos completos.
No existe una operación de acceso a cubos básicos análoga a la operación de acceso a cubos avanzados. DESCREMENTO
operación.
A continuación se muestra un ejemplo de la opción Avanzada DESCREMENTO
operación.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
función OnUpdate(doc, meta) { registro('input meta', meta); registro('input doc ', doc); // si doc.count no existe se creará var ctr_meta = {"id": "mi_contador_atómico:1" }; var resultado = couchbase.decremento(src_bkt,ctr_meta); si (resultado.éxito) { registro('éxito adv. decremento: resultado',resultado); } si no { registro('fallo adv. decremento: id',ctr_meta.id,resultado,resultado); } } |
Un valor de retorno de ejemplo, suponga que crea esto KEY "my_atomic_counter:1" DOC {"count": 23}
si se despliega la función Eventing anterior, el recuento se decrementará inmediatamente:
1 2 3 4 5 6 7 8 9 10 |
{ "doc": { "contar": 22 }, "meta": { "id": "clave::1", "cas": "1609374770297176064" }, "éxito": verdadero } |
Referencias