{"id":3955,"date":"2017-08-22T10:00:34","date_gmt":"2017-08-22T17:00:34","guid":{"rendered":"https:\/\/www.couchbase.com\/blog\/?p=3955"},"modified":"2025-06-13T17:32:59","modified_gmt":"2025-06-14T00:32:59","slug":"aggregate-grouping-n1ql-mapreduce","status":"publish","type":"post","link":"https:\/\/www.couchbase.com\/blog\/pt\/aggregate-grouping-n1ql-mapreduce\/","title":{"rendered":"Agrupamento de agregados com N1QL \/ MapReduce"},"content":{"rendered":"<div class=\"paragraph\">\n<p>Agrupamento agregado \u00e9 o t\u00edtulo desta postagem do blog, mas n\u00e3o sei se \u00e9 o melhor nome. Voc\u00ea j\u00e1 usou a fun\u00e7\u00e3o <a href=\"https:\/\/dev.mysql.com\/doc\/refman\/5.7\/en\/group-by-functions.html#function_group-concat\">Fun\u00e7\u00e3o GROUP_CONCAT<\/a> ou o <a href=\"https:\/\/stackoverflow.com\/questions\/451415\/simulating-group-concat-mysql-function-in-microsoft-sql-server-2005\"><code>PARA XML PATH('')<\/code> solu\u00e7\u00e3o alternativa no SQL Server<\/a>? \u00c9 basicamente sobre isso que estou escrevendo hoje. Com o Couchbase Server, a maneira mais f\u00e1cil de fazer isso \u00e9 com a fun\u00e7\u00e3o N1QL <code>ARRAY_AGG<\/code> mas voc\u00ea tamb\u00e9m pode fazer isso com uma visualiza\u00e7\u00e3o antiga do MapReduce.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>Estou escrevendo este post porque um de nossos engenheiros de solu\u00e7\u00f5es estava trabalhando nesse problema para um cliente (que n\u00e3o ter\u00e1 seu nome revelado). Nenhum de n\u00f3s conseguiu encontrar uma postagem de blog como esta com a resposta, portanto, depois de trabalharmos juntos para chegar a uma solu\u00e7\u00e3o, decidi que escreveria sobre ela para o meu futuro eu (que \u00e9 praticamente o principal motivo pelo qual escrevo qualquer coisa, na verdade. O outro motivo \u00e9 descobrir se mais algu\u00e9m conhece uma maneira melhor).<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>Antes de come\u00e7armos, disponibilizei algum material se voc\u00ea quiser acompanhar o processo. O c\u00f3digo-fonte que usei para gerar os dados do \"paciente\" usados nesta postagem <a href=\"https:\/\/github.com\/couchbaselabs\/blog-source-code\/tree\/master\/Groves\/076GroupConcateN1qlAndMapReduce\/src\">est\u00e1 dispon\u00edvel no GitHub<\/a>. Se voc\u00ea n\u00e3o tiver conhecimento de .NET, poder\u00e1 usar apenas <a href=\"https:\/\/developer.couchbase.com\/documentation\/server\/current\/tools\/cbimport.html\">cbimport<\/a> em <a href=\"https:\/\/github.com\/couchbaselabs\/blog-source-code\/blob\/master\/Groves\/076GroupConcateN1qlAndMapReduce\/src\/GenerateData\/GenerateData\/patients.json\">dados de amostra<\/a> que eu criei. (Ou voc\u00ea pode usar o <a href=\"https:\/\/query.pub.couchbase.com\/tutorial\/#1\">\u00c1rea restrita N1QL<\/a>mais informa\u00e7\u00f5es sobre isso mais tarde). O restante desta postagem do blog pressup\u00f5e que voc\u00ea tenha um bucket de \"pacientes\" com esses dados de amostra.<\/p>\n<\/div>\n<div class=\"sect1\">\n<h2 id=\"_requirements\">Requisitos<\/h2>\n<div class=\"sectionbody\">\n<div class=\"paragraph\">\n<p>Tenho um conjunto de documentos de pacientes. Cada paciente tem um \u00fanico m\u00e9dico. O documento do paciente se refere a um m\u00e9dico por um campo chamado <code>doctorId<\/code>. Pode haver outros dados no documento do paciente, mas nosso foco principal \u00e9 a chave do documento do paciente e o <code>doctorId<\/code> valor. Alguns exemplos:<\/p>\n<\/div>\n<div class=\"listingblock\">\n<div class=\"content\">\n<pre class=\"highlight decode:true\"><code class=\"language-JavaScript\">key 01257721\r\n{\r\n    \"doctorId\": 58,\r\n    \"patientName\": \"Robyn Kirby\",\r\n    \"patientDob\": \"1986-05-16T19:01:52.4075881-04:00\"\r\n}\r\n\r\nkey 116wmq8i\r\n{\r\n    \"doctorId\": 8,\r\n    \"patientName\": \"Helen Clark\",\r\n    \"patientDob\": \"2016-02-01T04:54:30.3505879-05:00\"\r\n}<\/code><\/pre>\n<\/div>\n<\/div>\n<div class=\"paragraph\">\n<p>Em seguida, podemos presumir que cada m\u00e9dico pode ter v\u00e1rios pacientes. Tamb\u00e9m podemos presumir que existe um documento do m\u00e9dico, mas n\u00e3o precisamos disso para este tutorial, portanto, vamos nos concentrar apenas nos pacientes por enquanto.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>Por fim, o que queremos para o nosso aplicativo (ou relat\u00f3rio ou qualquer outro) \u00e9 um agrupamento agregado dos pacientes com seus m\u00e9dicos. Cada registro identificaria um m\u00e9dico e uma lista\/array\/cole\u00e7\u00e3o de pacientes. Algo como:<\/p>\n<\/div>\n<table class=\"tableblock frame-all grid-all spread\">\n<colgroup>\n<col style=\"width: 50%\" \/>\n<col style=\"width: 50%\" \/> <\/colgroup>\n<thead>\n<tr>\n<th class=\"tableblock halign-left valign-top\">m\u00e9dico<\/th>\n<th class=\"tableblock halign-left valign-top\">pacientes<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td class=\"tableblock halign-left valign-top\">\n<p class=\"tableblock\">58<\/p>\n<\/td>\n<td class=\"tableblock halign-left valign-top\">\n<p class=\"tableblock\">01257721, 450mkkri, 8g2mrze2 ...<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"tableblock halign-left valign-top\">\n<p class=\"tableblock\">8<\/p>\n<\/td>\n<td class=\"tableblock halign-left valign-top\">\n<p class=\"tableblock\">05woknfk, 116wmq8i, 2t5yttqi ...<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"tableblock halign-left valign-top\">\n<p class=\"tableblock\">... etc ...<\/p>\n<\/td>\n<td class=\"tableblock halign-left valign-top\">\n<p class=\"tableblock\">... etc ...<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<div class=\"paragraph\">\n<p>Isso pode ser \u00fatil para um painel que mostre todos os pacientes atribu\u00eddos a m\u00e9dicos, por exemplo. Como podemos obter os dados nesse formato, com o N1QL ou com o MapReduce?<\/p>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"sect1\">\n<h2 id=\"_n1ql_aggregate_grouping\">N1QL Agrupamento agregado<\/h2>\n<div class=\"sectionbody\">\n<div class=\"paragraph\">\n<p><a href=\"https:\/\/www.couchbase.com\/blog\/pt\/products\/n1ql\/\">N1QL<\/a> nos d\u00e1 o <a href=\"https:\/\/developer.couchbase.com\/documentation\/server\/current\/n1ql\/n1ql-language-reference\/arrayfun.html\"><code>ARRAY_AGG<\/code> fun\u00e7\u00e3o<\/a> para tornar isso poss\u00edvel.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>Comece selecionando o doctorId de cada documento do paciente e a chave do documento do paciente. Em seguida, aplique <code>ARRAY_AGG<\/code> para o ID do documento do paciente. Por fim, agrupe os resultados pelo doctorId.<\/p>\n<\/div>\n<div class=\"listingblock\">\n<div class=\"content\">\n<pre class=\"highlight decode:true\"><code class=\"language-SQL\">SELECT p.doctorId AS doctor, ARRAY_AGG(META(p).id) AS patients\r\nFROM patients p\r\nGROUP BY p.doctorId;<\/code><\/pre>\n<\/div>\n<\/div>\n<div class=\"paragraph\">\n<p><em>Observa\u00e7\u00e3o: n\u00e3o se esque\u00e7a de executar <code>CREATE PRIMARY INDEX ON patients (criar \u00edndice prim\u00e1rio em pacientes)<\/code> para que este tutorial ative uma varredura de \u00edndice prim\u00e1rio.<\/em><\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>Imagine essa consulta sem o <code>ARRAY_AGG<\/code>. Ele retornaria um registro para cada paciente. Ao adicionar o <code>ARRAY_AGG<\/code> e o <code>GRUPO POR<\/code>ele agora retorna um registro para cada m\u00e9dico.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>Aqui est\u00e1 um trecho dos resultados do conjunto de dados de amostra que criei:<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p><span class=\"image\"><img decoding=\"async\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2017\/08\/07501-aggregate-grouping-n1ql.png\" alt=\"Aggregate grouping results in N1QL\" \/><\/span><\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>Se n\u00e3o quiser se dar ao trabalho de criar um bucket e importar dados de amostra, voc\u00ea tamb\u00e9m pode tentar isso no <a href=\"https:\/\/query.pub.couchbase.com\/tutorial\/#1\">Sandbox do tutorial N1QL<\/a>. N\u00e3o h\u00e1 documentos de pacientes l\u00e1, portanto, a consulta ser\u00e1 um pouco diferente.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>Vou agrupar os e-mails por idade. Comece selecionando a idade de cada documento e o e-mail de cada documento. Em seguida, aplique <code>ARRAY_AGG<\/code> para o e-mail. Por fim, agrupe os resultados por idade.<\/p>\n<\/div>\n<div class=\"listingblock\">\n<div class=\"content\">\n<pre class=\"highlight decode:true\"><code class=\"language-SQL\">SELECT t.age AS age, ARRAY_AGG(t.email) AS emails\r\nFROM tutorial t\r\ngroup by t.age;<\/code><\/pre>\n<\/div>\n<\/div>\n<div class=\"paragraph\">\n<p>Aqui est\u00e1 uma captura de tela de alguns dos resultados da \u00e1rea restrita:<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p><span class=\"image\"><img decoding=\"async\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2017\/08\/07503-n1ql-sandbox.png\" alt=\"N1QL sandbox results\" \/><\/span><\/p>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"sect1\">\n<h2 id=\"_aggregate_group_with_mapreduce\">Grupo agregado com MapReduce<\/h2>\n<div class=\"sectionbody\">\n<div class=\"paragraph\">\n<p>Um agrupamento agregado semelhante tamb\u00e9m pode ser obtido com uma visualiza\u00e7\u00e3o do MapReduce.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>Comece criando uma nova visualiza\u00e7\u00e3o. No Console do Couchbase, v\u00e1 para \u00cdndices e depois para Visualiza\u00e7\u00f5es. Selecione o bucket \"patients\" (pacientes). Clique em \"Create Development View\" (Criar visualiza\u00e7\u00e3o de desenvolvimento). Nomeie um documento de design (chamei o meu de \"_design\/dev_patient\"). Crie uma visualiza\u00e7\u00e3o, chamei a minha de \"doctorPatientGroup\".<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>Precisaremos de um Map e de uma fun\u00e7\u00e3o Reduce personalizada.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>Primeiro, para o mapa, queremos apenas o doctorId (em uma matriz, j\u00e1 que usaremos agrupamento) e o ID do documento do paciente.<\/p>\n<\/div>\n<div class=\"listingblock\">\n<div class=\"content\">\n<pre class=\"highlight decode:true\"><code class=\"language-JavaScript\">function (doc, meta) {\r\n    emit([doc.doctorId], meta.id);\r\n}<\/code><\/pre>\n<\/div>\n<\/div>\n<div class=\"paragraph\">\n<p>Em seguida, para a fun\u00e7\u00e3o reduce, pegaremos os valores e os concatenaremos em uma matriz. Abaixo est\u00e1 uma maneira de fazer isso. N\u00e3o tenho a pretens\u00e3o de ser um especialista em JavaScript ou em MapReduce, portanto, pode haver uma maneira mais eficiente de lidar com isso:<\/p>\n<\/div>\n<div class=\"listingblock\">\n<div class=\"content\">\n<pre class=\"highlight decode:true\"><code class=\"language-JavaScript\">function reduce(key, values, rereduce) {\r\n    var merged = [].concat.apply([], values);\r\n    return merged;\r\n}<\/code><\/pre>\n<\/div>\n<\/div>\n<div class=\"paragraph\">\n<p>Depois de criar as fun\u00e7\u00f5es map e reduce, salve o \u00edndice.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>Por fim, ao chamar esse \u00edndice, defina group_level como 1. Voc\u00ea pode fazer isso na interface do usu\u00e1rio:<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p><span class=\"image\"><img decoding=\"async\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2017\/08\/07502-aggregate-grouping-mapreduce.png\" alt=\"Aggregate grouping with MapReduce\" \/><\/span><\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>Ou voc\u00ea pode fazer isso a partir do URL do \u00edndice. Aqui est\u00e1 um exemplo de um cluster em execu\u00e7\u00e3o em minha m\u00e1quina local:<\/p>\n<\/div>\n<div class=\"listingblock\">\n<div class=\"content\">\n<pre class=\"highlight decode:true\"><code class=\"language-JavaScript\">https:\/\/127.0.0.1:8092\/patients\/_design\/dev_patients\/_view\/doctorPatientGroup?connection_timeout=60000&amp;full_set=true&amp;group_level=1&amp;inclusive_end=true&amp;skip=0&amp;stale=false<\/code><\/pre>\n<\/div>\n<\/div>\n<div class=\"paragraph\">\n<p>O resultado dessa exibi\u00e7\u00e3o deve ser semelhante a este (truncado para ficar mais bonito em uma postagem de blog):<\/p>\n<\/div>\n<div class=\"listingblock\">\n<div class=\"content\">\n<pre class=\"highlight decode:true\"><code class=\"language-JavaScript\">{\"rows\":[\r\n{\"key\":[0],\"value\":[\"reo8th6f\",\"g53x9e8d\", ... ]},\r\n{\"key\":[1],\"value\":[\"k4xkhmki\",\"g1jtc0oj\", ... ]},\r\n{\"key\":[2],\"value\":[\"spp6gf3k\",\"3z93wyan\"]},\r\n{\"key\":[3],\"value\":[\"qnx93fh3\",\"gssusiun\", ...]},\r\n{\"key\":[4],\"value\":[\"qvqgb0ve\",\"jm0g69zz\", ...]},\r\n{\"key\":[5],\"value\":[\"ywjfvad6\",\"so4uznxx\", ...]}\r\n...\r\n]}<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"sect1\">\n<h2 id=\"_summary\">Resumo<\/h2>\n<div class=\"sectionbody\">\n<div class=\"paragraph\">\n<p>Acho que o m\u00e9todo N1QL \u00e9 mais f\u00e1cil, mas pode haver benef\u00edcios de desempenho ao usar o MapReduce em alguns casos. Em ambos os casos, \u00e9 poss\u00edvel realizar o agrupamento agregado com a mesma facilidade (se n\u00e3o mais) que em um banco de dados relacional.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>Interessado em saber mais sobre o N1QL? N\u00e3o deixe de dar uma olhada na se\u00e7\u00e3o <a href=\"https:\/\/query.pub.couchbase.com\/tutorial\/#1\">tutorial\/sandbox completo do N1QL<\/a>. Interessado em visualiza\u00e7\u00f5es de MapReduce? D\u00ea uma olhada na se\u00e7\u00e3o <a href=\"https:\/\/developer.couchbase.com\/documentation\/server\/current\/sdk\/dotnet\/view-queries-with-sdk.html\">Documenta\u00e7\u00e3o das visualiza\u00e7\u00f5es do MapReduce<\/a> para come\u00e7ar.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>Voc\u00ea achou esta postagem \u00fatil? Tem sugest\u00f5es para melhorar? Deixe um coment\u00e1rio abaixo ou entre em contato comigo em <a href=\"https:\/\/twitter.com\/mgroves\">Twitter @mgroves<\/a>.<\/p>\n<\/div>\n<\/div>\n<\/div>","protected":false},"excerpt":{"rendered":"<p>Aggregate grouping is what I\u2019m titling this blog post, but I don\u2019t know if it\u2019s the best name. Have you ever used MySQL\u2019s GROUP_CONCAT function or the FOR XML PATH(&#8221;) workaround in SQL Server? That\u2019s basically what I\u2019m writing about [&hellip;]<\/p>","protected":false},"author":71,"featured_media":3956,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[1814,1816,1819,1812],"tags":[2041,2042],"ppma_author":[8937],"class_list":["post-3955","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-application-design","category-couchbase-server","category-data-modeling","category-n1ql-query","tag-aggregation","tag-grouping"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v25.8 (Yoast SEO v25.8) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Aggregate grouping with N1QL \/ MapReduce - The Couchbase Blog<\/title>\n<meta name=\"description\" content=\"Aggregate grouping (similar to GROUP_CONCAT) can be done in Couchbase Server with N1QL&#039;s ARRAY_AGG or with a MapReduce View.\" \/>\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\/pt\/aggregate-grouping-n1ql-mapreduce\/\" \/>\n<meta property=\"og:locale\" content=\"pt_BR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Aggregate grouping with N1QL \/ MapReduce\" \/>\n<meta property=\"og:description\" content=\"Aggregate grouping (similar to GROUP_CONCAT) can be done in Couchbase Server with N1QL&#039;s ARRAY_AGG or with a MapReduce View.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.couchbase.com\/blog\/pt\/aggregate-grouping-n1ql-mapreduce\/\" \/>\n<meta property=\"og:site_name\" content=\"The Couchbase Blog\" \/>\n<meta property=\"article:published_time\" content=\"2017-08-22T17:00:34+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-06-14T00:32:59+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2017\/08\/075-hero-aggregate-grouping.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1280\" \/>\n\t<meta property=\"og:image:height\" content=\"731\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Matthew Groves\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@mgroves\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Matthew Groves\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"5 minutos\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/aggregate-grouping-n1ql-mapreduce\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/aggregate-grouping-n1ql-mapreduce\/\"},\"author\":{\"name\":\"Matthew Groves\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/3929663e372020321b0152dc4fa65a58\"},\"headline\":\"Aggregate grouping with N1QL \/ MapReduce\",\"datePublished\":\"2017-08-22T17:00:34+00:00\",\"dateModified\":\"2025-06-14T00:32:59+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/aggregate-grouping-n1ql-mapreduce\/\"},\"wordCount\":901,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/aggregate-grouping-n1ql-mapreduce\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2017\/08\/075-hero-aggregate-grouping.jpg\",\"keywords\":[\"aggregation\",\"grouping\"],\"articleSection\":[\"Application Design\",\"Couchbase Server\",\"Data Modeling\",\"SQL++ \/ N1QL Query\"],\"inLanguage\":\"pt-BR\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/aggregate-grouping-n1ql-mapreduce\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/aggregate-grouping-n1ql-mapreduce\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/aggregate-grouping-n1ql-mapreduce\/\",\"name\":\"Aggregate grouping with N1QL \/ MapReduce - The Couchbase Blog\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/aggregate-grouping-n1ql-mapreduce\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/aggregate-grouping-n1ql-mapreduce\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2017\/08\/075-hero-aggregate-grouping.jpg\",\"datePublished\":\"2017-08-22T17:00:34+00:00\",\"dateModified\":\"2025-06-14T00:32:59+00:00\",\"description\":\"Aggregate grouping (similar to GROUP_CONCAT) can be done in Couchbase Server with N1QL's ARRAY_AGG or with a MapReduce View.\",\"breadcrumb\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/aggregate-grouping-n1ql-mapreduce\/#breadcrumb\"},\"inLanguage\":\"pt-BR\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/aggregate-grouping-n1ql-mapreduce\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/aggregate-grouping-n1ql-mapreduce\/#primaryimage\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2017\/08\/075-hero-aggregate-grouping.jpg\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2017\/08\/075-hero-aggregate-grouping.jpg\",\"width\":1280,\"height\":731,\"caption\":\"Aggregate grouping - licensed through Creative Commons https:\/\/commons.wikimedia.org\/wiki\/File:Spices_of_Sa%C3%BAde_flea_market,_S%C3%A3o_Paulo,_Brazil.jpg\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/aggregate-grouping-n1ql-mapreduce\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.couchbase.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Aggregate grouping with N1QL \/ MapReduce\"}]},{\"@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\":\"pt-BR\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\",\"name\":\"The Couchbase Blog\",\"url\":\"https:\/\/www.couchbase.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@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\/3929663e372020321b0152dc4fa65a58\",\"name\":\"Matthew Groves\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/ba51e6aacc53995c323a634e4502ef54\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/70feb1b28a099ad0112b8d21fe1e81e1a4524beed3e20b7f107d5370e85a07ab?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/70feb1b28a099ad0112b8d21fe1e81e1a4524beed3e20b7f107d5370e85a07ab?s=96&d=mm&r=g\",\"caption\":\"Matthew Groves\"},\"description\":\"Matthew D. Groves is a guy who loves to code. It doesn't matter if it's C#, jQuery, or PHP: he'll submit pull requests for anything. He has been coding professionally ever since he wrote a QuickBASIC point-of-sale app for his parent's pizza shop back in the 90s. He currently works as a Senior Product Marketing Manager for Couchbase. His free time is spent with his family, watching the Reds, and getting involved in the developer community. He is the author of AOP in .NET, Pro Microservices in .NET, a Pluralsight author, and a Microsoft MVP.\",\"sameAs\":[\"https:\/\/crosscuttingconcerns.com\",\"https:\/\/x.com\/mgroves\"],\"url\":\"https:\/\/www.couchbase.com\/blog\/pt\/author\/matthew-groves\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Aggregate grouping with N1QL \/ MapReduce - The Couchbase Blog","description":"Aggregate grouping (similar to GROUP_CONCAT) can be done in Couchbase Server with N1QL's ARRAY_AGG or with a MapReduce View.","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\/pt\/aggregate-grouping-n1ql-mapreduce\/","og_locale":"pt_BR","og_type":"article","og_title":"Aggregate grouping with N1QL \/ MapReduce","og_description":"Aggregate grouping (similar to GROUP_CONCAT) can be done in Couchbase Server with N1QL's ARRAY_AGG or with a MapReduce View.","og_url":"https:\/\/www.couchbase.com\/blog\/pt\/aggregate-grouping-n1ql-mapreduce\/","og_site_name":"The Couchbase Blog","article_published_time":"2017-08-22T17:00:34+00:00","article_modified_time":"2025-06-14T00:32:59+00:00","og_image":[{"width":1280,"height":731,"url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2017\/08\/075-hero-aggregate-grouping.jpg","type":"image\/jpeg"}],"author":"Matthew Groves","twitter_card":"summary_large_image","twitter_creator":"@mgroves","twitter_misc":{"Written by":"Matthew Groves","Est. reading time":"5 minutos"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.couchbase.com\/blog\/aggregate-grouping-n1ql-mapreduce\/#article","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/aggregate-grouping-n1ql-mapreduce\/"},"author":{"name":"Matthew Groves","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/3929663e372020321b0152dc4fa65a58"},"headline":"Aggregate grouping with N1QL \/ MapReduce","datePublished":"2017-08-22T17:00:34+00:00","dateModified":"2025-06-14T00:32:59+00:00","mainEntityOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/aggregate-grouping-n1ql-mapreduce\/"},"wordCount":901,"commentCount":0,"publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/aggregate-grouping-n1ql-mapreduce\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2017\/08\/075-hero-aggregate-grouping.jpg","keywords":["aggregation","grouping"],"articleSection":["Application Design","Couchbase Server","Data Modeling","SQL++ \/ N1QL Query"],"inLanguage":"pt-BR","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.couchbase.com\/blog\/aggregate-grouping-n1ql-mapreduce\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.couchbase.com\/blog\/aggregate-grouping-n1ql-mapreduce\/","url":"https:\/\/www.couchbase.com\/blog\/aggregate-grouping-n1ql-mapreduce\/","name":"Aggregate grouping with N1QL \/ MapReduce - The Couchbase Blog","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/aggregate-grouping-n1ql-mapreduce\/#primaryimage"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/aggregate-grouping-n1ql-mapreduce\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2017\/08\/075-hero-aggregate-grouping.jpg","datePublished":"2017-08-22T17:00:34+00:00","dateModified":"2025-06-14T00:32:59+00:00","description":"Aggregate grouping (similar to GROUP_CONCAT) can be done in Couchbase Server with N1QL's ARRAY_AGG or with a MapReduce View.","breadcrumb":{"@id":"https:\/\/www.couchbase.com\/blog\/aggregate-grouping-n1ql-mapreduce\/#breadcrumb"},"inLanguage":"pt-BR","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.couchbase.com\/blog\/aggregate-grouping-n1ql-mapreduce\/"]}]},{"@type":"ImageObject","inLanguage":"pt-BR","@id":"https:\/\/www.couchbase.com\/blog\/aggregate-grouping-n1ql-mapreduce\/#primaryimage","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2017\/08\/075-hero-aggregate-grouping.jpg","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2017\/08\/075-hero-aggregate-grouping.jpg","width":1280,"height":731,"caption":"Aggregate grouping - licensed through Creative Commons https:\/\/commons.wikimedia.org\/wiki\/File:Spices_of_Sa%C3%BAde_flea_market,_S%C3%A3o_Paulo,_Brazil.jpg"},{"@type":"BreadcrumbList","@id":"https:\/\/www.couchbase.com\/blog\/aggregate-grouping-n1ql-mapreduce\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.couchbase.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Aggregate grouping with N1QL \/ MapReduce"}]},{"@type":"WebSite","@id":"https:\/\/www.couchbase.com\/blog\/#website","url":"https:\/\/www.couchbase.com\/blog\/","name":"Blog do Couchbase","description":"Couchbase, o banco de dados 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":"pt-BR"},{"@type":"Organization","@id":"https:\/\/www.couchbase.com\/blog\/#organization","name":"Blog do Couchbase","url":"https:\/\/www.couchbase.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"pt-BR","@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\/3929663e372020321b0152dc4fa65a58","name":"Matthew Groves","image":{"@type":"ImageObject","inLanguage":"pt-BR","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/ba51e6aacc53995c323a634e4502ef54","url":"https:\/\/secure.gravatar.com\/avatar\/70feb1b28a099ad0112b8d21fe1e81e1a4524beed3e20b7f107d5370e85a07ab?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/70feb1b28a099ad0112b8d21fe1e81e1a4524beed3e20b7f107d5370e85a07ab?s=96&d=mm&r=g","caption":"Matthew Groves"},"description":"Matthew D. Groves \u00e9 um cara que adora programar. N\u00e3o importa se \u00e9 C#, jQuery ou PHP: ele enviar\u00e1 solicita\u00e7\u00f5es de pull para qualquer coisa. Ele tem programado profissionalmente desde que escreveu um aplicativo de ponto de venda QuickBASIC para a pizzaria de seus pais nos anos 90. Atualmente, ele trabalha como gerente s\u00eanior de marketing de produtos da Couchbase. Seu tempo livre \u00e9 passado com a fam\u00edlia, assistindo aos Reds e participando da comunidade de desenvolvedores. Ele \u00e9 autor de AOP in .NET, Pro Microservices in .NET, autor da Pluralsight e Microsoft MVP.","sameAs":["https:\/\/crosscuttingconcerns.com","https:\/\/x.com\/mgroves"],"url":"https:\/\/www.couchbase.com\/blog\/pt\/author\/matthew-groves\/"}]}},"authors":[{"term_id":8937,"user_id":71,"is_guest":0,"slug":"matthew-groves","display_name":"Matthew Groves","avatar_url":"https:\/\/secure.gravatar.com\/avatar\/70feb1b28a099ad0112b8d21fe1e81e1a4524beed3e20b7f107d5370e85a07ab?s=96&d=mm&r=g","author_category":"","last_name":"Groves","first_name":"Matthew","job_title":"","user_url":"https:\/\/crosscuttingconcerns.com","description":"Matthew D. Groves \u00e9 um cara que adora programar.  N\u00e3o importa se \u00e9 C#, jQuery ou PHP: ele enviar\u00e1 solicita\u00e7\u00f5es de pull para qualquer coisa.  Ele tem programado profissionalmente desde que escreveu um aplicativo de ponto de venda QuickBASIC para a pizzaria de seus pais nos anos 90.  Atualmente, ele trabalha como gerente s\u00eanior de marketing de produtos da Couchbase. Seu tempo livre \u00e9 passado com a fam\u00edlia, assistindo aos Reds e participando da comunidade de desenvolvedores.  Ele \u00e9 autor de AOP in .NET, Pro Microservices in .NET, autor da Pluralsight e Microsoft MVP."}],"_links":{"self":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/posts\/3955","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/users\/71"}],"replies":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/comments?post=3955"}],"version-history":[{"count":0,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/posts\/3955\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/media\/3956"}],"wp:attachment":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/media?parent=3955"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/categories?post=3955"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/tags?post=3955"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/ppma_author?post=3955"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}