Diseño de aplicaciones

Agrupación agregada con N1QL / MapReduce

Agrupación agregada es como voy a titular esta entrada del blog, pero no sé si es el mejor nombre. ¿Alguna vez has utilizado MySQL Función GROUP_CONCAT o el PARA XML RUTA('') solución en SQL Server? Eso es básicamente sobre lo que estoy escribiendo hoy. Con Couchbase Server, la forma más fácil de hacerlo es con N1QL's ARRAY_AGG pero también puedes hacerlo con una vista MapReduce de la vieja escuela.

Escribo este post porque uno de nuestros ingenieros de soluciones estaba trabajando en este problema para un cliente (cuyo nombre se mantendrá en el anonimato). Ninguno de los dos pudo encontrar una entrada de blog como esta con la respuesta, así que después de trabajar juntos para encontrar una solución, decidí que escribiría un blog sobre ello para mi futuro yo (que es más o menos la razón principal por la que escribo cualquier cosa, en realidad. La otra razón es saber si alguien conoce una forma mejor).

Antes de empezar, he puesto a tu disposición algo de material por si quieres seguirme la pista. El código fuente que utilicé para generar los datos del "paciente" utilizados en este post está disponible en GitHub. Si no eres experto en .NET, puedes utilizar cbimport en datos de muestra que he creado. (O, puede utilizar el Caja de arena N1QL(más información al respecto más adelante). El resto de esta entrada del blog asume que usted tiene un cubo "pacientes" con los datos de la muestra en el mismo.

Requisitos

Tengo un cubo de documentos de pacientes. Cada paciente tiene un único médico. El documento del paciente se refiere a un médico mediante un campo llamado doctorId. Puede haber otros datos en el documento del paciente, pero nos centramos principalmente en la clave del documento del paciente y el doctorId valor. Algunos ejemplos:

A continuación, podemos suponer que cada médico puede tener varios pacientes. También podemos suponer que existe un documento de médico, pero en realidad no lo necesitamos para este tutorial, así que vamos a centrarnos en los pacientes por ahora.

Por último, lo que queremos para nuestra aplicación (o informe o lo que sea), es una agrupación agregada de los pacientes con su médico. Cada registro identificaría un médico y una lista/array/colección de pacientes. Algo así como

doctor pacientes

58

01257721, 450mkkri, 8g2mrze2 ...

8

05woknfk, 116wmq8i, 2t5yttqi ...

... etc ...

... etc ...

Esto podría ser útil para un cuadro de mando que muestre todos los pacientes asignados a médicos, por ejemplo. Cómo podemos obtener los datos de esta forma, con N1QL o con MapReduce?

N1QL Agrupación agregada

N1QL nos da la ARRAY_AGG función para hacerlo posible.

Empiece seleccionando el doctorId de cada documento de paciente, y la clave del documento de paciente. A continuación, aplique ARRAY_AGG al ID del documento del paciente. Por último, agrupe los resultados por el doctorId.

Nota: no olvides ejecutar CREAR ÍNDICE PRIMARIO EN pacientes para este tutorial para habilitar un escaneo de índice primario.

Imagínese esta consulta sin ARRAY_AGG. Devolvería un registro por cada paciente. Añadiendo el ARRAY_AGG y el GRUPO PORahora devuelve un registro por cada médico.

A continuación se muestra un fragmento de los resultados en el conjunto de datos de muestra que he creado:

Aggregate grouping results in N1QL

Si no quiere tomarse la molestia de crear un cubo e importar datos de muestra, también puede intentarlo en la función Sandbox tutorial N1QL. No hay documentos de pacientes, por lo que la consulta será un poco diferente.

Voy a agrupar los correos electrónicos por edad. Empieza seleccionando la edad de cada documento, y el email de cada documento. A continuación, aplica ARRAY_AGG al correo electrónico. Por último, agrupa los resultados por edad.

Aquí tienes una captura de pantalla de algunos de los resultados del sandbox:

N1QL sandbox results

Grupo agregado con MapReduce

También se puede lograr una agrupación agregada similar con una vista MapReduce.

Empieza creando una nueva Vista. Desde la consola de Couchbase, ve a Índices y luego a Vistas. Selecciona el bucket "pacientes". Haz clic en "Crear vista de desarrollo". Nombra un documento de diseño (yo llamé al mío "_design/dev_patient". Crea una vista, yo llamé a la mía "doctorPatientGroup".

Necesitaremos tanto una función Map como una función Reduce personalizada.

En primer lugar, para el mapa, sólo queremos el doctorId (en una matriz, ya que vamos a utilizar la agrupación) y el ID del documento del paciente.

A continuación, para la función reducir, tomaremos los valores y los concatenaremos en un array. A continuación se muestra una forma en que usted puede hacerlo. No pretendo ser un experto en JavaScript o un experto en MapReduce, por lo que podría haber una manera más eficiente para hacer frente a esto:

Una vez creadas las funciones map y reduce, guarda el índice.

Por último, cuando llame a este índice, establezca group_level en 1. Puede hacerlo en la interfaz de usuario:

Aggregate grouping with MapReduce

O puede hacerlo desde la URL del índice. He aquí un ejemplo de un clúster que se ejecuta en mi máquina local:

El resultado de esa vista debería tener este aspecto (truncado para que quede más bonito en una entrada de blog):

Resumen

Creo que el método N1QL es más fácil, pero puede haber beneficios de rendimiento para el uso de MapReduce en algunos casos. En cualquier caso, se puede lograr la agrupación agregada tan fácilmente (si no más fácilmente) como en una base de datos relacional.

¿Quieres saber más sobre N1QL? No deje de consultar el tutorial/sandbox completo de N1QL. ¿Le interesan las vistas MapReduce? Eche un vistazo a las Documentación sobre MapReduce Views para empezar.

¿Le ha resultado útil este post? ¿Tiene sugerencias para mejorarlo? Deje un comentario a continuación o póngase en contacto conmigo en Twitter @mgroves.

Comparte este artículo
Recibe actualizaciones del blog de Couchbase en tu bandeja de entrada
Este campo es obligatorio.

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.

Deja un comentario

¿Listo para empezar con Couchbase Capella?

Empezar a construir

Consulte nuestro portal para desarrolladores para explorar NoSQL, buscar recursos y empezar con tutoriales.

Utilizar Capella gratis

Ponte manos a la obra con Couchbase en unos pocos clics. Capella DBaaS es la forma más fácil y rápida de empezar.

Póngase en contacto

¿Quieres saber más sobre las ofertas de Couchbase? Permítanos ayudarle.