{"id":4498,"date":"2018-02-12T10:00:54","date_gmt":"2018-02-12T18:00:54","guid":{"rendered":"https:\/\/www.couchbase.com\/blog\/?p=4498"},"modified":"2025-06-13T20:09:22","modified_gmt":"2025-06-14T03:09:22","slug":"join-queries-couchbase-mobile","status":"publish","type":"post","link":"https:\/\/www.couchbase.com\/blog\/pt\/join-queries-couchbase-mobile\/","title":{"rendered":"Apresentando as consultas JOIN no Couchbase Mobile"},"content":{"rendered":"<p>O Couchbase Lite 2.0 suporta a capacidade de realizar JOINS em seus documentos JSON. Isso faz parte da nova interface de consulta baseada em <a href=\"https:\/\/www.couchbase.com\/blog\/pt\/products\/n1ql\/\">N1QL<\/a>a linguagem de consulta declarativa do Couchbase que estende o SQL para JSON. Se voc\u00ea estiver familiarizado com SQL, vai se sentir em casa com a sem\u00e2ntica da nova API.<\/p>\n<p>Os JOINS permitem que voc\u00ea combine o conte\u00fado de v\u00e1rios documentos. Nesta publica\u00e7\u00e3o, forneceremos exemplos para ilustrar os tipos de JOINS poss\u00edveis com o Couchbase Lite. Para cada uma das consultas, forneceremos a consulta SQL equivalente. Este blog pressup\u00f5e que voc\u00ea esteja familiarizado com os fundamentos da nova API de consulta, portanto, se ainda n\u00e3o tiver feito isso, n\u00e3o deixe de revisar o artigo <a href=\"https:\/\/www.couchbase.com\/blog\/pt\/sql-for-json-query-interface-couchbase-mobile\/\">postagem anterior<\/a> primeiro. Se estiver interessado, os links para blogs que discutem outros recursos da interface do Query s\u00e3o fornecidos no final desta publica\u00e7\u00e3o.<\/p>\n<p>Voc\u00ea pode fazer o download das compila\u00e7\u00f5es mais recentes do Couchbase Mobile 2.0 Pre-Release em nosso <a href=\"https:\/\/developer.couchbase.com\/documentation\/mobile\/2.0\/whatsnew.html\">downloads<\/a> p\u00e1gina.<\/p>\n<p><!--more--><\/p>\n<h3 id=\"background\">Hist\u00f3rico<\/h3>\n<p>Se voc\u00ea estava usando as vers\u00f5es 1.x do Couchbase Mobile, provavelmente est\u00e1 familiarizado com <a href=\"https:\/\/developer.couchbase.com\/documentation\/mobile\/1.4\/training\/develop\/using-the-database\/index.html#query-documents\">Visualiza\u00e7\u00f5es de mapas<\/a> para criar \u00edndices e consultas. Na vers\u00e3o 2.0, voc\u00ea n\u00e3o precisa mais criar visualiza\u00e7\u00f5es e fun\u00e7\u00f5es de mapa! Em vez disso, uma interface simples permite a cria\u00e7\u00e3o de \u00edndices e voc\u00ea pode usar uma interface do Query Builder para construir suas consultas. A nova interface de consulta \u00e9 mais simples de usar e muito mais poderosa em compara\u00e7\u00e3o. Vamos descobrir alguns de seus recursos nesta postagem.<\/p>\n<h3 id=\"sampleproject\">Projeto de amostra<\/h3>\n<p>Embora os exemplos discutidos aqui usem o Swift para iOS, a mesma interface de consulta tamb\u00e9m \u00e9 compat\u00edvel com as plataformas Android e Windows.<\/p>\n<p><strong>Portanto, com alguns pequenos ajustes, voc\u00ea poder\u00e1 reutilizar os exemplos de consulta desta postagem ao trabalhar com outras plataformas.<\/strong><\/p>\n<p>Siga as instru\u00e7\u00f5es abaixo se voc\u00ea estiver interessado em um projeto Swift de amostra<\/p>\n<ul>\n<li>Clone o iOS Swift Playground do GitHub<\/li>\n<\/ul>\n<pre><code>$ git clone https:\/\/github.com\/couchbaselabs\/couchbase-lite-ios-api-playground<\/code><\/pre>\n<ul>\n<li>Siga as instru\u00e7\u00f5es de instala\u00e7\u00e3o no manual correspondente <a href=\"https:\/\/github.com\/couchbaselabs\/couchbase-lite-ios-api-playground\/blob\/master\/README.md\">LEIAME<\/a> para criar e executar o playground.<\/li>\n<\/ul>\n<h3 id=\"sampledatamodel\">Modelo de dados de amostra<\/h3>\n<p>Usaremos um banco de dados de amostra localizado <a href=\"https:\/\/github.com\/couchbaselabs\/couchbase-lite-ios-api-playground\/tree\/master\/joindb.cblite2\">aqui<\/a>. Voc\u00ea pode incorporar esse banco de dados pr\u00e9-criado em seu aplicativo m\u00f3vel e come\u00e7ar a us\u00e1-lo para suas consultas.<\/p>\n<p>O conjunto de dados de amostra \u00e9 um pouco artificial, mas o objetivo aqui \u00e9 demonstrar alguns casos de uso t\u00edpicos de <code>unir-se<\/code> consultas.<\/p>\n<ul>\n<li>\"Documento do tipo \"funcion\u00e1rio<\/li>\n<\/ul>\n<pre class=\"lang:js decode:true\">{\r\n \"type\": \"employee\",\r\n \"firstname\": \"John\",\r\n \"lastname\": \"Smith\",\r\n \"department\": \"1000\",\r\n \"location\": \"101\"\r\n}<\/pre>\n<ul>\n<li>\"Documento do tipo \"departamento<\/li>\n<\/ul>\n<pre class=\"lang:js decode:true\">{\r\n \"type\": \"department\",\r\n \"name\": \"Product Management\",\r\n \"code\": \"2000\",\r\n \"head\": {\r\n \"firstname\": \"Patricia\",\r\n \"lastname\": \"Shoji\"\r\n },\r\n \"location\":[\"101\",\"102\"]\r\n}\r\n<code><\/code><\/pre>\n<ul>\n<li>Documento do tipo \"location\" (local)<\/li>\n<\/ul>\n<pre class=\"lang:js decode:true\">{\r\n \"type\": \"location\",\r\n \"name\": \"HQ\",\r\n \"address\": \"1123 6th St. Melbourne, FL 32904 \",\r\n \"code\": \"101\"\r\n}<\/pre>\n<p>** Consulte o modelo acima para cada um dos exemplos de consulta abaixo. **<\/p>\n<h3 id=\"thedatabasehandle\">O identificador do banco de dados<\/h3>\n<p>Nas consultas abaixo, usaremos o <a href=\"https:\/\/developer.couchbase.com\/documentation\/mobile\/2.0\/guides\/couchbase-lite\/native-api\/database\/index.html\"><code>Banco de dados<\/code><\/a> API para abrir\/criar o banco de dados CouchbaseLite.<\/p>\n<pre class=\"wrap:true lang:swift decode:true\"> let options = DatabaseConfiguration()\r\n let db = try Database(name: kDBName, config: options)<\/pre>\n<h3 id=\"indexes\">\u00cdndices<\/h3>\n<p>Para acelerar as consultas de leitura, voc\u00ea pode criar \u00edndices nas propriedades que ser\u00e3o consultadas. A melhoria no desempenho seria significativa em grandes conjuntos de dados. Obviamente, esteja ciente de que haver\u00e1 um aumento na necessidade de armazenamento para guardar os \u00edndices, e o desempenho das grava\u00e7\u00f5es tamb\u00e9m poder\u00e1 ser afetado. Portanto, tenha cuidado ao criar muitos \u00edndices.<\/p>\n<p>O exemplo a seguir cria um <code>\u00cdndice de valor<\/code> no <code>tipo<\/code> propriedade de um documento<\/p>\n<pre class=\"wrap:true lang:swift decode:true\"> try db.createIndex(IndexBuilder.valueIndex(items: ValueIndexItem.property(\"type\")),withName: \"typeIndex\")<\/pre>\n<h3 id=\"joinorinnerjoin\">JOIN ou Inner JOIN<\/h3>\n<p>Voc\u00ea pode usar uma consulta JOIN ou Inner JOIN simples para buscar propriedades dos documentos participantes se e somente se ambos os documentos atenderem \u00e0s condi\u00e7\u00f5es especificadas no <code>ON<\/code> cl\u00e1usula.<\/p>\n<p>Por exemplo, considerando o modelo de dados que apresentamos anteriormente, vamos supor que voc\u00ea queira buscar o <code>firstName<\/code>, <code>lastName<\/code> de um \"funcion\u00e1rio\" e o correspondente <code>nome<\/code> do \"departamento\" ao qual o funcion\u00e1rio pertencia. Nesse caso, <code>primeiro nome<\/code> e <code>sobrenome<\/code> as propriedades s\u00e3o obtidas do documento de <code>tipo<\/code> \"funcion\u00e1rio\" e o departamento <code>nome<\/code> \u00e9 obtido do documento de <code>tipo<\/code> \"departamento\" se e somente se o <code>departamento<\/code> da propriedade \"employee\" corresponde \u00e0 propriedade <code>c\u00f3digo<\/code> propriedade no \"departamento\"<\/p>\n<p>Isso implica que, se n\u00e3o houver documentos de \"departamento\" que correspondam ao <code>c\u00f3digo<\/code> no documento \"employee\", os detalhes desse funcion\u00e1rio n\u00e3o ser\u00e3o inclu\u00eddos no resultado de sa\u00edda<\/p>\n<figure><img decoding=\"async\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2018\/01\/inner_join_explain.png\" alt=\"\" \/><\/figure>\n<h4 id=\"request\">Solicita\u00e7\u00e3o<\/h4>\n<pre class=\"wrap:true lang:swift decode:true\"> try db.createIndex(IndexBuilder.valueIndex(items: ValueIndexItem.property(\"type\")),withName: \"typeIndex\")\r\n\/\/ set up aliases to represent the data source for &amp;quot;department&amp;quot; type document\r\nlet departmentDS = DataSource.database(db).as(\"departmentDS\")\r\n\r\n\/\/ Property expression for &amp;quot;department&amp;quot; (in employee documents)\r\nlet employeeDeptExpr = Expression.property(\"department\").from(\"employeeDS\")\r\n\r\n\/\/ Property expression for &amp;quot;code&amp;quot; (in department documents)\r\nlet departmentCodeExpr = Expression.property(\"code\").from(\"departmentDS\")\r\n\r\n\/\/ Join clause: Join employee type and department type documents where the\r\n\/\/ \"department\" field of employee documents is equal to the department \"code\";\r\n\/\/ of \"department\" documents\r\nlet joinExpr = employeeDeptExpr.equalTo(departmentCodeExpr)\r\n    .and(Expression.property(\"type\").from(\"employeeDS\").equalTo(Expression.string(\"employee\")))\r\n    .and(Expression.property(\"type\").from(\"departmentDS\").equalTo(Expression.string(\"department\")))\r\n\r\n\r\n\/\/ Construct inner join expression with ON query.\r\nlet join = Join.join(departmentDS).on(joinExpr)\r\n\r\n\/\/ return the \"firstname\", \"lastname\"; and \"department\"; name from the documents that are joined based\r\n\/\/ on the JOIN expression\r\nlet searchQuery = Query.select(\r\n    SelectResult.expression(Expression.property(\"firstname\").from(\"employeeDS\")),\r\n    SelectResult.expression(Expression.property(\"lastname\").from(\"employeeDS\")),\r\n    SelectResult.expression(Expression.property(\"name\").from(\"departmentDS\")))\r\n    .from(employeeDS)\r\n    .join(join)<\/pre>\n<p>&nbsp;<\/p>\n<h4>ANSI SQL<\/h4>\n<p>A instru\u00e7\u00e3o SQL equivalente para a consulta acima seria<\/p>\n<pre class=\"wrap:true lang:mysql decode:true\">SELECT\r\n  employeeDS.firstname,\r\n  employeeDS.lastname,\r\n  departmentDS.name\r\nFROM\r\n  `travel-sample` employeeDS\r\n  INNER JOIN `travel-sample` departmentDS ON employeeDS.department = departmentDS.code\r\nWHERE\r\n  employeeDS.type = \"employee\"\r\n  AND departmentDS.type = \"department\"<\/pre>\n<p>&nbsp;<\/p>\n<h3 id=\"leftjoinorleftouterjoin\">Left JOIN ou Left Outer JOIN<\/h3>\n<p>Voc\u00ea pode usar uma consulta JOIN \u00e0 esquerda para obter propriedades dos documentos participantes se ambos os documentos atenderem \u00e0s condi\u00e7\u00f5es especificadas no <code>ON<\/code> cl\u00e1usula. No entanto, diferentemente de um JOIN regular, os resultados tamb\u00e9m incluir\u00e3o documentos n\u00e3o correspondentes no lado esquerdo da cl\u00e1usula <code>ON<\/code> da express\u00e3o JOIN.<\/p>\n<p>Por exemplo, considerando o modelo de dados que apresentamos anteriormente, vamos supor que voc\u00ea queira buscar o <code>firstName<\/code>, <code>lastName<\/code> de um \"funcion\u00e1rio\" e o correspondente <code>nome<\/code> do \"departamento\" ao qual o funcion\u00e1rio pertencia.<br \/>\nAl\u00e9m disso, vamos supor que tamb\u00e9m estejamos interessados no<code>firstName<\/code> e <code>lastName<\/code> de um \"funcion\u00e1rio\" cujo <code>departamento<\/code> c\u00f3digo faz <em>n\u00e3o<\/em> corresponde a um departamento v\u00e1lido. Esse poderia ser o caso, por exemplo, se o <code>departamento<\/code> O c\u00f3digo do funcion\u00e1rio foi inserido incorretamente.<\/p>\n<p>Nesse caso, <code>primeiro nome<\/code> e <code>sobrenome<\/code> as propriedades s\u00e3o obtidas do documento de <code>tipo<\/code> \"funcion\u00e1rio\" e o departamento <code>nome<\/code> \u00e9 obtido do documento de <code>tipo<\/code> \"departamento\" se o <code>departamento<\/code> da propriedade \"employee\" corresponde \u00e0 propriedade <code>c\u00f3digo<\/code> propriedade no \"departamento\".<\/p>\n<p>Se n\u00e3o houver um departamento correspondente, somente o <code>primeiro nome<\/code> e <code>sobrenome<\/code> do documento \"employee\" s\u00e3o retornadas.<\/p>\n<figure><img decoding=\"async\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2018\/01\/outer_join_explain.png\" alt=\"\" \/><\/figure>\n<h4 id=\"request\">Solicita\u00e7\u00e3o<\/h4>\n<pre class=\"wrap:true lang:swift decode:true\"> \/\/ set up aliases to represent the data source for \"employee\" type document\r\n let employeeDS = DataSource.database(db).as(\"employeeDS\")\r\n\/\/ set up aliases to represent the data source for \"department\" type document\r\nlet departmentDS = DataSource.database(db).as(\"departmentDS\")\r\n\r\n\/\/ Property expression for \"department\" (in employee documents)\r\nlet employeeDeptExpr = Expression.property(\"department\").from(\"employeeDS\")\r\n\r\n\/\/ Property expression for \"code\" (in department documents)\r\nlet departmentCodeExpr = Expression.property(&amp;quot;code&amp;quot;).from(\"departmentDS\")\r\n\r\n\/\/ Join clause: Join department type and employee type documents where the\r\n\/\/ \"department\" field of employee documents is equal to the department \"code\" of\r\n\/\/ \"department\" documents\r\nlet joinExpr = employeeDeptExpr.equalTo(departmentCodeExpr)\r\n    .and(Expression.property(\"type\").from(\"employeeDS\").equalTo(Expression.string(\"employee\")))\r\n    .and(Expression.property(\"type\").from(\"departmentDS\").equalTo(Expression.string(\"department\")))\r\n\r\n\r\n\/\/ join expression with ON query\r\nlet join = Join.leftJoin(departmentDS).on(joinExpr)\r\n\r\n\/\/ return the \"firstname\", \"lastname\" and \"department\" name from the documents that are joined based on the JOIN expression\r\n let searchQuery = Query.select(\r\n     SelectResult.expression(Expression.property(\"firstname\").from(\"employeeDS\")),\r\n     SelectResult.expression(Expression.property(\"lastname\").from(\"employeeDS\")),\r\n     SelectResult.expression(Expression.property(\"name\").from(\"departmentDS\")))\r\n    .from(employeeDS)\r\n    .join(join)<\/pre>\n<h4>ANSI SQL<\/h4>\n<p>A instru\u00e7\u00e3o SQL equivalente para a consulta acima seria<\/p>\n<pre class=\"wrap:true lang:mysql decode:true\"> SELECT\r\n  employeeDS.firstname,\r\n  employeeDS.lastname,\r\n  departmentDS.name\r\nFROM\r\n  `travel-sample` employeeDS\r\n  LEFT JOIN `travel-sample` departmentDS ON employeeDS.department = departmentDS.code\r\nWHERE\r\n  employeeDS.type = \"employee\"\r\n  AND departmentDS.type = \"department\"<\/pre>\n<p>&nbsp;<\/p>\n<h3 id=\"crossjoin\">Cross JOIN<\/h3>\n<p>Voc\u00ea pode usar uma consulta cross JOIN para buscar o produto cartesiano das propriedades dos documentos participantes, que normalmente n\u00e3o est\u00e3o relacionados entre si. Isso \u00e9 o equivalente a um inner JOIN <em>sem<\/em> o <code>ON<\/code> da express\u00e3o de uni\u00e3o.<\/p>\n<p>Por exemplo, considerando o modelo de dados que apresentamos anteriormente, vamos supor que voc\u00ea queira buscar o produto cartesiano de todos os documentos de <code>tipo<\/code> \"localiza\u00e7\u00e3o\" e <code>tipo<\/code> \"departamento\". Em outras palavras, cada \"local\" <code>tipo<\/code> seria combinado com cada um dos documentos do \"departamento\" <code>tipo<\/code> documentos.<\/p>\n<p>Como n\u00e3o h\u00e1 <code>em<\/code> especificada na express\u00e3o cross JOIN, voc\u00ea precisaria incluir uma cl\u00e1usula <code>onde<\/code> para filtrar o subconjunto de documentos a ser considerado com base no documento <code>tipo<\/code>.<\/p>\n<figure><img decoding=\"async\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2018\/01\/cross_join_explain.png\" alt=\"\" \/><\/figure>\n<h4 id=\"request\">Solicita\u00e7\u00e3o<\/h4>\n<pre class=\"wrap:true lang:swift decode:true\">\/\/ set up aliases to represent the data source for \"department\" type document\r\n let departmentDS = DataSource.database(db).as(\"departmentDS\")\r\n\/\/ set up aliases to represent the data source for \"location\" type document\r\nlet locationDS = DataSource.database(db).as(\"locationDS\")\r\n\r\n\/\/ Property expression for \"department\" (in employee documents)\r\nlet employeeDeptExpr = Expression.property(\"code\").from(\"departmentDS\")\r\n\r\n\/\/ Property expression for \"department\" (in location documents)\r\nlet departmentCodeExpr = Expression.property(\"code\").from(\"locationDS\")\r\n\r\n\/\/ cross join expression\r\nlet join = Join.crossJoin(locationDS)\r\n\r\n\/\/ type property expressions\r\nlet deptTypeExpr = Expression.property(\"type\").from(\"departmentDS\")\r\nlet locationTypeExpr = Expression.property(\"type\").from(\"locationDS\")\r\n\r\n\/\/ The where clauses filters the set of documents to cross-join on\r\n\/\/ We alias the \"code\" properties since it exists in both the department and location docs\r\n\r\n\/\/ NOTE: The where clause is used to filter the documents to be considered as\r\n\/\/ part of the cartesian join\r\nlet searchQuery = Query.select(\r\n    SelectResult.expression(Expression.property(\"name\").from(\"departmentDS\")).as(\"DeptName\"),\r\n     SelectResult.expression(Expression.property(\"name\").from(\"locationDS\")).as(\"LocationName\"),\r\n    SelectResult.expression(Expression.property(\"address\").from(\"locationDS\")))\r\n    .from(departmentDS)\r\n    .join(join)\r\n    .where(deptTypeExpr.equalTo(Expression.string(\"department\"))\r\n                .and(locationTypeExpr.equalTo(Expression.string(\"location\"))))<\/pre>\n<h4>ANSI SQL<\/h4>\n<p>A instru\u00e7\u00e3o SQL equivalente para a consulta acima seria<\/p>\n<pre class=\"wrap:true lang:mysql decode:true\">SELECT\r\n  departmentDS.name AS DeptName,\r\n  locationDS.name AS LocationName,\r\n  locationDS.address\r\nFROM\r\n  `travel-sample` departmentDS\r\n  CROSS JOIN `travel-sample` locationDS\r\nWHERE\r\n  departmentDS.type = \"department\"<\/pre>\n<p>&nbsp;<\/p>\n<h3 id=\"chainingofjoins\">Encadeamento de JOINs<\/h3>\n<p>\u00c9 poss\u00edvel especificar v\u00e1rias express\u00f5es JOIN em seu <code>selecionar<\/code> para poder unir-se a documentos com base em crit\u00e9rios diferentes.<\/p>\n<p>Por exemplo, considerando o modelo de dados que apresentamos anteriormente, vamos supor que voc\u00ea queira buscar o <code>firstName<\/code>, <code>lastName<\/code> de um \"funcion\u00e1rio\" e o correspondente <code>nome<\/code> do \"departamento\" ao qual o funcion\u00e1rio pertencia. Al\u00e9m disso, voc\u00ea tamb\u00e9m queria identificar o <code>nome<\/code> do \"local\" em que o funcion\u00e1rio estava baseado.<\/p>\n<p>Nesse caso, usamos duas express\u00f5es JOIN.<br \/>\nA primeira express\u00e3o JOIN \u00e9 usada para unir documentos de <code>tipo<\/code> \"funcion\u00e1rio\" com documentos de <code>tipo<\/code> \"department\" com base na propriedade \"department code\". Nesse caso, a propriedade <code>primeiro nome<\/code> e <code>sobrenome<\/code> as propriedades s\u00e3o obtidas do documento de <code>tipo<\/code> \"funcion\u00e1rio\" e o departamento <code>nome<\/code> \u00e9 obtido do documento de <code>tipo<\/code> \"departamento\" se e somente se o <code>departamento<\/code> da propriedade \"employee\" corresponde \u00e0 propriedade <code>c\u00f3digo<\/code> propriedade no \"departamento\".<\/p>\n<p>A segunda express\u00e3o JOIN \u00e9 usada para unir documentos de <code>tipo<\/code> \"funcion\u00e1rio\" com documentos de <code>tipo<\/code> \"location\" com base na propriedade \"location code\". Nesse caso, a propriedade <code>primeiro nome<\/code> e <code>sobrenome<\/code> as propriedades s\u00e3o obtidas do documento de <code>tipo<\/code> \"funcion\u00e1rio\" e o local <code>nome<\/code> \u00e9 obtido do documento de <code>tipo<\/code> \"localiza\u00e7\u00e3o\" se e somente se o <code>localiza\u00e7\u00e3o<\/code> da propriedade \"employee\" corresponde \u00e0 propriedade <code>c\u00f3digo<\/code> propriedade no \"departamento\".<\/p>\n<figure><img decoding=\"async\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2018\/01\/multi-join.png\" alt=\"\" \/><\/figure>\n<h4 id=\"request\">Solicita\u00e7\u00e3o<\/h4>\n<pre class=\"wrap:true lang:swift decode:true\"> \/\/ set up aliases to represent the data source for \"employee\" type document\r\n let employeeDS = DataSource.database(db).as(\"employeeDS\")\r\n \/\/ set up aliases to represent the data source for \"department\" type document\r\n let departmentDS = DataSource.database(db).as(\"departmentDS\")\r\n \/\/ set up aliases to represent the data source for \"location\" type document\r\n let locationDS = DataSource.database(db).as(\"locationDS\")\r\n \/\/ Property expression for \"department\"  property (in employee documents)   \r\n let employeeDeptExpr = Expression.property(\"department\").from(\"employeeDS\")\r\n\r\n \/\/ Property expression for \"location\"  property (in employee documents) \r\n let employeeLocationExpr = Expression.property(\"location\").from(\"employeeDS\")\r\n\r\n \/\/ Property expression for \"code\"  property (in department documents) \r\n let departmentCodeExpr = Expression.property(\"code\").from(\"departmentDS\")\r\n\r\n \/\/ Property expression for \"code\"  property (in location documents) \r\n let locationCodeExpr = Expression.property(\"code\").from(\"locationDS\")\r\n    \r\n \/\/ Join Criteria 1\r\n \/\/ Join where the \"department\" field of employee documents is equal to the department \"code\" of \"department\" documents\r\n let joinDeptCodeExpr = employeeDeptExpr.equalTo(departmentCodeExpr)\r\n        .and(Expression.property(\"type\").from(\"employeeDS\").equalTo(Expression.string(\"employee\")))\r\n        .and(Expression.property(\"type\").from(\"departmentDS\").equalTo(Expression.string(\"department\")))\r\n    \r\n\r\n \/\/ Join Criteria 2\r\n \/\/ Join where the \"department\" field of employee documents is equal to the department \"code\" of \"department\" documents\r\n let joinLocationCodeExpr = employeeLocationExpr.equalTo(locationCodeExpr)\r\n        .and(Expression.property(\"type\").from(\"employeeDS\").equalTo(Expression.string(\"employee\")))\r\n        .and(Expression.property(\"type\").from(\"locationDS\").equalTo(Expression.string(\"location\")))\r\n    \r\n \/\/ join expression for department code\r\n let joinDeptCode = Join.join(departmentDS).on(joinDeptCodeExpr)\r\n    \r\n \/\/ join expression for location code\r\n let joinLocationCode = Join.join(locationDS).on(joinLocationCodeExpr)\r\n    \r\n \/\/ Multiple join expressions in the join clause\r\n let searchQuery = QueryBuilder.select(SelectResult.expression(Expression.property(\"firstname\").from(\"employeeDS\")),\r\n       SelectResult.expression(Expression.property(\"lastname\").from(\"employeeDS\")),\r\n       SelectResult.expression(Expression.property(\"name\").from(\"departmentDS\")).as(\"deptName\"),\r\n       SelectResult.expression(Expression.property(\"name\").from(\"locationDS\")).as(\"locationName\"))\r\n        .from(employeeDS)\r\n        .join(joinDeptCode,joinLocationCode)<\/pre>\n<h3><\/h3>\n<h4>ANSI SQL<\/h4>\n<p>A instru\u00e7\u00e3o SQL equivalente para a consulta acima seria<\/p>\n<pre class=\"wrap:true lang:mysql decode:true\">SELECT\r\n  employeeDS.firstname,\r\n  employeeDS.lastname,\r\n  departmentDS.name AS deptName,\r\n  locationDS.name AS locationName\r\nFROM\r\n  `travel-sample` employeeDS\r\n  JOIN `travel-sample` departmentDS ON employeeDS.department = departmentDS.code\r\n  JOIN `travel-sample` locationDS ON employeeDS.location = locationDS.code\r\nWHERE\r\n  departmentDS.type = \"department\"\r\n  AND locationDS.type = \"location\"\r\n  AND employeeDS.type = \"employee\"<\/pre>\n<p>&nbsp;<\/p>\n<h3 id=\"joinexpressionswithfunctions\">JOIN Express\u00f5es com fun\u00e7\u00f5es<\/h3>\n<p>Embora todos os exemplos tenham usado o <code>igual a<\/code> na express\u00e3o JOIN, deve-se observar que voc\u00ea pode usar qualquer operador de compara\u00e7\u00e3o, como <code>entre<\/code>, <code>greaterThanOrEqualTo<\/code> e assim por diante na express\u00e3o JOIN. Voc\u00ea tamb\u00e9m pode incluir qualquer <code>Fun\u00e7\u00e3o<\/code> express\u00f5es. Esse \u00e9 um recurso poderoso.<\/p>\n<p>Por exemplo, considerando o modelo de dados que apresentamos anteriormente, vamos supor que voc\u00ea queira buscar o departamento <code>nome<\/code> e correspondente <code>localiza\u00e7\u00e3o<\/code> nomes do \"local\" onde o departamento estava baseado. Um departamento pode pertencer a um ou mais locais.<br \/>\nNesse caso, a express\u00e3o JOIN uniria documentos do tipo \"department\" (departamento) e \"location\" (local) procurando correspond\u00eancias em qualquer um dos membros da tabela <code>localiza\u00e7\u00e3o<\/code> do documento do departamento usando a propriedade de matriz <code>ArrayFunction<\/code> express\u00e3o.<\/p>\n<figure><img decoding=\"async\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2018\/02\/join_expression.png\" alt=\"\" \/><\/figure>\n<pre class=\"wrap:true lang:swift decode:true\">\/\/ set up aliases to represent the data source for \"department\" type document\r\n let departmentDS = DataSource.database(db).as(\"departmentDS\")\r\n\/\/ set up aliases to represent the data source for \"location\" type document\r\nlet locationDS = DataSource.database(db).as(\"locationDS\")\r\n\r\n\/\/ Property expression for &amp;quot;location&amp;quot;  property (in department documents)\r\nlet departmentLocationExpr = Expression.property(\"location\").from(\"departmentDS\")\r\n\r\n\/\/ Property expression for \"code\" property (in location documents)\r\nlet locationCodeExpr = Expression.property(\"code\").from(\"locationDS\")\r\n\r\n\/\/ Join where the \"code\" field of location documents is contained in\r\n\/\/ the \"location\"  array of \"department\" documents\r\nlet joinDeptCodeExpr = ArrayFunction.contains(departmentLocationExpr, value: locationCodeExpr)\r\n    .and(Expression.property(\"type\").from(\"locationDS\").equalTo(Expression.string(\"location\"))\r\n    .and(Expression.property(\"type\").from(\"departmentDS\").equalTo(Expression.string(\"department\"))))\r\n\r\n\/\/ join expression\r\nlet joinLocationCode = Join.join(departmentDS).on(joinDeptCodeExpr)\r\n\r\n\/\/ Search query with JOIN\r\nlet searchQuery = QueryBuilder.select(\r\nSelectResult.expression(Expression.property(\"name\").from(\"departmentDS\")).as(\"departmentName\"),\r\n    SelectResult.expression(Expression.property(\"name\").from(\"locationDS\")).as(\"locationName\"))\r\n    .from(locationDS)\r\n    .join(joinLocationCode)<\/pre>\n<p>&nbsp;<\/p>\n<h4>ANSI SQL<\/h4>\n<p>As matrizes n\u00e3o s\u00e3o compat\u00edveis com o SQL. Entretanto, o N1QL inclui suporte para matrizes. A instru\u00e7\u00e3o do tipo SQL correspondente para a consulta acima seria<\/p>\n<pre class=\"wrap:true lang:mysql decode:true\">SELECT\r\n  departmentDS.name AS departmentName,\r\n  locationDS.name AS locationName\r\nFROM\r\n  `travel-sample` locationDS\r\n  JOIN `travel-sample` departmentDS ON \r\n    ANY code IN departmentDS.location SATISFIES code = locationDS.location\r\n    END \r\n  \r\nWHERE\r\n  departmentDS.type = \"department\"\r\n  AND locationDS.type = \"location\"<\/pre>\n<p>&nbsp;<\/p>\n<h3 id=\"whatnext\">O que vem a seguir<\/h3>\n<p>Esta postagem do blog analisou o poderoso recurso JOIN do Couchbase Mobile 2.0, que permite combinar resultados de v\u00e1rios documentos JSON. Voc\u00ea pode <a href=\"https:\/\/www.couchbase.com\/blog\/pt\/downloads\/\">download<\/a> Couchbase Mobile 2.0 e teste as consultas discutidas nesta publica\u00e7\u00e3o. Isso \u00e9 um come\u00e7o. Espere ver mais funcionalidades em vers\u00f5es futuras.<\/p>\n<p>Aqui est\u00e3o algumas outras postagens relacionadas ao Couchbase Mobile Query que podem ser de interesse<br \/>\n- Isso <a href=\"https:\/\/www.couchbase.com\/blog\/pt\/sql-for-json-query-interface-couchbase-mobile\/\">postagem no blog<\/a> discute os fundamentos<br \/>\n- Isso <a href=\"https:\/\/www.couchbase.com\/blog\/pt\/querying-array-collections-couchbase-mobile\/\">postagem no blog<\/a> discute como consultar cole\u00e7\u00f5es de matrizes<br \/>\n- Isso <a href=\"https:\/\/www.couchbase.com\/blog\/pt\/full-text-search-couchbase-mobile-2-0\/\">postagem no blog<\/a> discute os recursos de pesquisa de texto completo (FTS).<\/p>\n<p>Se tiver d\u00favidas ou coment\u00e1rios, deixe um coment\u00e1rio abaixo ou entre em contato comigo pelo Twitter\u00a0<a href=\"https:\/\/twitter.com\/rajagp\">@rajagp<\/a>\u00a0ou envie-me um e-mail\u00a0<a href=\"mailto:priya.rajagopal@couchbase.com\">priya.rajagopal@couchbase.com<\/a>.  O\u00a0<a href=\"https:\/\/www.couchbase.com\/blog\/pt\/forums\/\">F\u00f3runs do Couchbase<\/a> s\u00e3o outro bom lugar para entrar em contato com perguntas.<\/p>","protected":false},"excerpt":{"rendered":"<p>Couchbase Lite 2.0 supports the ability to perform JOINS across your JSON documents . This is part of the new Query interface based on N1QL, Couchbase\u2019s declarative query language that extends SQL for JSON. If you are familiar with SQL, [&hellip;]<\/p>","protected":false},"author":1423,"featured_media":4586,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[1815,7667,1810,1812],"tags":[2004],"ppma_author":[8948],"class_list":["post-4498","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-best-practices-and-tutorials","category-couchbase-lite","category-couchbase-mobile","category-n1ql-query","tag-couchbase-mobile-2-0"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v25.7.1 (Yoast SEO v25.7) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Introducing JOIN Queries in Couchbase Mobile - The Couchbase Blog<\/title>\n<meta name=\"description\" content=\"This post discusses how you can JOIN JSON documents in Couchbase Mobile. This capability allows you to combine the contents of multiple JSON documents.\" \/>\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\/join-queries-couchbase-mobile\/\" \/>\n<meta property=\"og:locale\" content=\"pt_BR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Introducing JOIN Queries in Couchbase Mobile\" \/>\n<meta property=\"og:description\" content=\"This post discusses how you can JOIN JSON documents in Couchbase Mobile. This capability allows you to combine the contents of multiple JSON documents.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.couchbase.com\/blog\/pt\/join-queries-couchbase-mobile\/\" \/>\n<meta property=\"og:site_name\" content=\"The Couchbase Blog\" \/>\n<meta property=\"article:published_time\" content=\"2018-02-12T18:00:54+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-06-14T03:09:22+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/02\/join_expression.png\" \/>\n\t<meta property=\"og:image:width\" content=\"722\" \/>\n\t<meta property=\"og:image:height\" content=\"483\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Priya Rajagopal, Senior Director, Product Management\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@rajagp\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Priya Rajagopal, Senior Director, Product Management\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"12 minutos\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/join-queries-couchbase-mobile\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/join-queries-couchbase-mobile\/\"},\"author\":{\"name\":\"Priya Rajagopal, Senior Director, Product Management\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/c2da90e57717ee4970c48a87a131ac2c\"},\"headline\":\"Introducing JOIN Queries in Couchbase Mobile\",\"datePublished\":\"2018-02-12T18:00:54+00:00\",\"dateModified\":\"2025-06-14T03:09:22+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/join-queries-couchbase-mobile\/\"},\"wordCount\":1438,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/join-queries-couchbase-mobile\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/02\/join_expression.png\",\"keywords\":[\"couchbase mobile 2.0\"],\"articleSection\":[\"Best Practices and Tutorials\",\"Couchbase Lite\",\"Couchbase Mobile\",\"SQL++ \/ N1QL Query\"],\"inLanguage\":\"pt-BR\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/join-queries-couchbase-mobile\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/join-queries-couchbase-mobile\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/join-queries-couchbase-mobile\/\",\"name\":\"Introducing JOIN Queries in Couchbase Mobile - The Couchbase Blog\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/join-queries-couchbase-mobile\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/join-queries-couchbase-mobile\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/02\/join_expression.png\",\"datePublished\":\"2018-02-12T18:00:54+00:00\",\"dateModified\":\"2025-06-14T03:09:22+00:00\",\"description\":\"This post discusses how you can JOIN JSON documents in Couchbase Mobile. This capability allows you to combine the contents of multiple JSON documents.\",\"breadcrumb\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/join-queries-couchbase-mobile\/#breadcrumb\"},\"inLanguage\":\"pt-BR\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/join-queries-couchbase-mobile\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/join-queries-couchbase-mobile\/#primaryimage\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/02\/join_expression.png\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/02\/join_expression.png\",\"width\":722,\"height\":483,\"caption\":\"join on array\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/join-queries-couchbase-mobile\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.couchbase.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Introducing JOIN Queries in Couchbase Mobile\"}]},{\"@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\/c2da90e57717ee4970c48a87a131ac2c\",\"name\":\"Priya Rajagopal, Senior Director, Product Management\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/4b50a54778b979d8c345b036ab138734\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/acfb2349788955262cd069497a9e7bdb0e97c26326f2e55811e7c1174e9ef1be?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/acfb2349788955262cd069497a9e7bdb0e97c26326f2e55811e7c1174e9ef1be?s=96&d=mm&r=g\",\"caption\":\"Priya Rajagopal, Senior Director, Product Management\"},\"description\":\"Priya Rajagopal is a Senior Director of Product Management at Couchbase responsible for developer platforms for the cloud and the edge. She has been professionally developing software for over 20 years in several technical and product leadership positions, with 10+ years focused on mobile technologies. As a TISPAN IPTV standards delegate, she was a key contributor to the IPTV standards specifications. She has 22 patents in the areas of networking and platform security.\",\"sameAs\":[\"https:\/\/x.com\/rajagp\"],\"url\":\"https:\/\/www.couchbase.com\/blog\/pt\/author\/priya-rajagopalcouchbase-com\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Introducing JOIN Queries in Couchbase Mobile - The Couchbase Blog","description":"This post discusses how you can JOIN JSON documents in Couchbase Mobile. This capability allows you to combine the contents of multiple JSON documents.","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\/join-queries-couchbase-mobile\/","og_locale":"pt_BR","og_type":"article","og_title":"Introducing JOIN Queries in Couchbase Mobile","og_description":"This post discusses how you can JOIN JSON documents in Couchbase Mobile. This capability allows you to combine the contents of multiple JSON documents.","og_url":"https:\/\/www.couchbase.com\/blog\/pt\/join-queries-couchbase-mobile\/","og_site_name":"The Couchbase Blog","article_published_time":"2018-02-12T18:00:54+00:00","article_modified_time":"2025-06-14T03:09:22+00:00","og_image":[{"width":722,"height":483,"url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/02\/join_expression.png","type":"image\/png"}],"author":"Priya Rajagopal, Senior Director, Product Management","twitter_card":"summary_large_image","twitter_creator":"@rajagp","twitter_misc":{"Written by":"Priya Rajagopal, Senior Director, Product Management","Est. reading time":"12 minutos"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.couchbase.com\/blog\/join-queries-couchbase-mobile\/#article","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/join-queries-couchbase-mobile\/"},"author":{"name":"Priya Rajagopal, Senior Director, Product Management","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/c2da90e57717ee4970c48a87a131ac2c"},"headline":"Introducing JOIN Queries in Couchbase Mobile","datePublished":"2018-02-12T18:00:54+00:00","dateModified":"2025-06-14T03:09:22+00:00","mainEntityOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/join-queries-couchbase-mobile\/"},"wordCount":1438,"commentCount":0,"publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/join-queries-couchbase-mobile\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/02\/join_expression.png","keywords":["couchbase mobile 2.0"],"articleSection":["Best Practices and Tutorials","Couchbase Lite","Couchbase Mobile","SQL++ \/ N1QL Query"],"inLanguage":"pt-BR","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.couchbase.com\/blog\/join-queries-couchbase-mobile\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.couchbase.com\/blog\/join-queries-couchbase-mobile\/","url":"https:\/\/www.couchbase.com\/blog\/join-queries-couchbase-mobile\/","name":"Introducing JOIN Queries in Couchbase Mobile - The Couchbase Blog","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/join-queries-couchbase-mobile\/#primaryimage"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/join-queries-couchbase-mobile\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/02\/join_expression.png","datePublished":"2018-02-12T18:00:54+00:00","dateModified":"2025-06-14T03:09:22+00:00","description":"This post discusses how you can JOIN JSON documents in Couchbase Mobile. This capability allows you to combine the contents of multiple JSON documents.","breadcrumb":{"@id":"https:\/\/www.couchbase.com\/blog\/join-queries-couchbase-mobile\/#breadcrumb"},"inLanguage":"pt-BR","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.couchbase.com\/blog\/join-queries-couchbase-mobile\/"]}]},{"@type":"ImageObject","inLanguage":"pt-BR","@id":"https:\/\/www.couchbase.com\/blog\/join-queries-couchbase-mobile\/#primaryimage","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/02\/join_expression.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/02\/join_expression.png","width":722,"height":483,"caption":"join on array"},{"@type":"BreadcrumbList","@id":"https:\/\/www.couchbase.com\/blog\/join-queries-couchbase-mobile\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.couchbase.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Introducing JOIN Queries in Couchbase Mobile"}]},{"@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\/c2da90e57717ee4970c48a87a131ac2c","name":"Priya Rajagopal, Diretora S\u00eanior, Gerenciamento de Produtos","image":{"@type":"ImageObject","inLanguage":"pt-BR","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/4b50a54778b979d8c345b036ab138734","url":"https:\/\/secure.gravatar.com\/avatar\/acfb2349788955262cd069497a9e7bdb0e97c26326f2e55811e7c1174e9ef1be?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/acfb2349788955262cd069497a9e7bdb0e97c26326f2e55811e7c1174e9ef1be?s=96&d=mm&r=g","caption":"Priya Rajagopal, Senior Director, Product Management"},"description":"Priya Rajagopal \u00e9 diretora s\u00eanior de gerenciamento de produtos da Couchbase, respons\u00e1vel pelas plataformas de desenvolvedor para a nuvem e a borda. Ela desenvolve software profissionalmente h\u00e1 mais de 20 anos em v\u00e1rios cargos t\u00e9cnicos e de lideran\u00e7a de produtos, com mais de 10 anos de foco em tecnologias m\u00f3veis. Como delegada de padr\u00f5es de IPTV da TISPAN, ela foi uma das principais colaboradoras das especifica\u00e7\u00f5es de padr\u00f5es de IPTV. Ela tem 22 patentes nas \u00e1reas de rede e seguran\u00e7a de plataforma.","sameAs":["https:\/\/x.com\/rajagp"],"url":"https:\/\/www.couchbase.com\/blog\/pt\/author\/priya-rajagopalcouchbase-com\/"}]}},"authors":[{"term_id":8948,"user_id":1423,"is_guest":0,"slug":"priya-rajagopalcouchbase-com","display_name":"Priya Rajagopal, Senior Director, Product Management","avatar_url":"https:\/\/secure.gravatar.com\/avatar\/acfb2349788955262cd069497a9e7bdb0e97c26326f2e55811e7c1174e9ef1be?s=96&d=mm&r=g","first_name":"Priya","last_name":"Rajagopal, Senior Director, Product Management","user_url":"","author_category":"","description":"Priya Rajagopal \u00e9 diretora s\u00eanior de gerenciamento de produtos da Couchbase, respons\u00e1vel pelas plataformas de desenvolvedor para a nuvem e a borda. Ela desenvolve software profissionalmente h\u00e1 mais de 20 anos em v\u00e1rios cargos t\u00e9cnicos e de lideran\u00e7a de produtos, com mais de 10 anos de foco em tecnologias m\u00f3veis. Como delegada de padr\u00f5es de IPTV da TISPAN, ela foi uma das principais colaboradoras das especifica\u00e7\u00f5es de padr\u00f5es de IPTV. Ela tem 22 patentes nas \u00e1reas de rede e seguran\u00e7a de plataforma."}],"_links":{"self":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/posts\/4498","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\/1423"}],"replies":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/comments?post=4498"}],"version-history":[{"count":0,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/posts\/4498\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/media\/4586"}],"wp:attachment":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/media?parent=4498"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/categories?post=4498"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/tags?post=4498"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/ppma_author?post=4498"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}