---
title: "SQL en Mongo (legacy)"
canonical: "https://onesaitplatform-es.refined.site/space/DOC/2215921334/SQL%20en%20Mongo%20(legacy)"
format: markdown
---
> ℹ️ **IMPORTANTE**
> ℹ️ 
> ℹ️ Esta guía aplica al motor SQL de consultas basado en Quasar, y que funcionaba para versiones Mongo hasta la 3.4 
> ℹ️ 
> ℹ️ Si usas el nuevo motor SQL o una versión de Mongo 4.X debes leer esta guía: [Nuevo SQL Engine on MongoDB](https://onesaitplatform.atlassian.net/wiki/spaces/DOC/pages/2215921647)


El Data Hub Semántico tiene entre otros objetivos **desacoplar la ontología de la base de datos subyacente.**

A tal fin, proponemos utilizar el lenguaje de consulta SQL, por lo que la plataforma ofrece un [Motor de Consulta SQL](https://quasar-analytics-documentation.readthedocs.io/en/latest/sql-squared-reference/) para cada una de las bases de datos soportadas.

Aquí encontrarás las guías de referencia de este lenguaje:

> Macro (toc)

# Operaciones SELECT

## Tipos de datos

| **Tipo** | **Descripción** | **Ejemplos** | **Soporte nativo en MongoDB** |
| --- | --- | --- | --- |
| Null | Indica que falta información. | `null` | Sí |
| Boolean | true o false (verdadero o falso). | `true`, `false` | Sí |
| Integer | Números enteros (sin componente fraccionario), | `1`, `-2` | Sí |
| Decimal | Números con decimales (componente fraccionario opcional). | `1.0`, `-2.19743` | Sí |
| String | Texto. | `'221B Baker Street'` | Sí |
| DateTime | Fecha y hora, en formato ISO8601. | `TIMESTAMP '2004-10-19 10:23:54'` | Sí |
| Time | Hora, en formato HH:MM:SS. | `TIME '10:23:54'` | No |
| Date | Fecha, en formato YYYY-MM-DD | `DATE '2004-10-19'` | No |
| Interval | Intervalo de tiempo, en formato ISO8601. | `INTERVAL 'P3DT4H5M6S'` | No |
| Object ID | Identificador único del objeto. | `OID '507f1f77bcf86cd799439011'` | Sí |
| Ordered Set | Lista ordenada que no permite duplicados. | `(1, 2, 3)` | No |
| Array | Lista ordenada que permite duplicados. | `[1, 2, 2]` | Sí |

## Cláusulas

Se soportan las siguientes cláusulas:

| **Tipo** | **Cláusulas** |
| --- | --- |
| Basic | `SELECT`, `AS`, `FROM` |
| Joins | `LEFT OUTER JOIN`, `RIGHT OUTER JOIN`, `INNER JOIN`, `FULL JOIN`, `CROSS` |
| Filtering | `WHERE` |
| Grouping | `GROUP BY`, `HAVING` |
| Conditional | `CASE` , `WHEN`, `DEFAULT` |
| Paging | `LIMIT`, `OFFSET` |
| Sorting | `ORDER BY` , `DESC`, `ASC` |

Se soportan las siguientes operaciones:

| **Tipo** | **Operadores** |
| --- | --- |
| Numeric | `+`, `-`, `*`, `/`, `%` |
| String | `~` , `~*`, `!~`, `!~*`, `LIKE`, `||` |
| Array | `||`, `[ ... ]` |
| Relational | `=`, `>=`, `<=`, `<>`, `BETWEEN`, `IN`, `NOT IN` |
| Boolean | `AND`, `OR`, `NOT` |
| Projection | `foo.bar`, `foo[2]`, `foo{*}`, `foo[*]` |
| Date/Time | `TIMESTAMP`, `DATE`, `INTERVAL`, `TIME` |
| Identity | `OID` |

**Nota:** `~` , `~*`, `!~` y `!~*` son operadores de expresiones regulares.  `~*`, `!~` `y``!~*` son preliminares y podrían no funcionar en la versión actual.

**Nota:** El operador `||` para cadenas (strings) concatenará dos cadenas. Por ejemplo, puedes crear un nombre completo a partir de una propiedad de nombre y apellido: `c.firstName || ' ' || c.lastName`. El operador `||` para matrices (arrays) concatenará dos matrices. Por ejemplo, si `xy` es una matriz con dos valores, entonces `c.xy || [0]` creará una matriz con tres valores, donde el tercer valor es cero.

Se soportan las siguientes funciones:

| **Tipo** | **Funciones** |
| --- | --- |
| String | `CONCAT`, `LOWER`, `UPPER`, `SUBSTRING`, `LENGTH`, `SEARCH` |
| DateTime | `DATE_PART`, `TO_TIMESTAMP` |
| Nulls | `COALESCE` |
| Arrays | `ARRAY_LENGTH`, `FLATTEN_ARRAY` |
| Objects | `FLATTEN_OBJECT` |
| Set-Level | `DISTINCT`, `DISTINCT_BY` |
| Aggregation | `COUNT`, `SUM`, `MIN`, `MAX`, `AVG` |
| Identity | `SQUASH` |

## Consultas básicas

<span style="color: #0000ff">select * from ISO3166_1 as c </span><span style="color: #000000">devuelve información y ContextData:</span>

![image](media://5d76b55e-4d08-4c54-bb31-e000cedf103d)

<span style="color: #0000ff">select c.ISO3166 as ISO3166 from ISO3166_1 as c</span> devuelve sólo Datos.

![image](media://e539aa15-a834-42e8-9705-bfd2aea9aeac)

<span style="color: #0000ff">select _id,c from ISO3166_1  </span>devuelve * incluyendo el id del Registro:

![image](media://84340059-c5dd-442e-92fa-590a93bc9200)


## Filtrado

Puedes filtrar un conjunto de resultados usando la cláusula WHERE. Se soportan los siguientes operadores:

- Relationales: `-`, `=`, `>=`, `<=`, `<>`, `BETWEEN`, `IN`, `NOT IN`
- Booleanos: `AND`, `OR`, `NOT`

**Ejemplos:**

<span style="color: #0000ff">select c.ISO3166 as ISO3166 from ISO3166_1 as c where </span>[<span style="color: #0000ff">c.ISO3166.name</span>](http://c.ISO3166.name)<span style="color: #0000ff">="Zambia"</span>

![image](media://292fcca9-9c0c-48f3-902b-95ebd57ec4e1)

## <span style="color: #000000">Operaciones numéricas y con cadenas (strings)</span>  


Puedes usar cualquiera de los operadores o funcionados listados en la sección [Cláusulas, Operadores y Funciones](https://quasar-analytics-documentation.readthedocs.io/en/latest/sql-squared-reference/#clauses-operators-functions) sobre números y cadenas. Algunos operadores y funciones comunes para cadenas incluyen:

| **Operador o función** | **Descripción** |
| --- | --- |
| `||` | Concatenata. |
| `LOWER` | Convierte a minúscula. |
| `UPPER` | Convierte a mayúscula. |
| `SUBSTRING` | Devuelve una sub-cadena. |
| `LENGTH` | Devuelve la longitud de la cadena. |

**Ejemplos:**

<span style="color: #0000ff">select c.ISO3166.number/100+1000 as calculated from ISO3166_1 as c where </span>[<span style="color: #0000ff">c.ISO3166.name</span>](http://c.ISO3166.name)<span style="color: #0000ff">="Zambia" and c.ISO3166.language="EN"</span>

![image](media://525dd3eb-3c11-4f94-996b-cb900cb4a98c)

<span style="color: #0000ff">select </span>[<span style="color: #0000ff">c.ISO3166.name</span>](http://c.ISO3166.name)<span style="color: #0000ff"> as name from ISO3166_1 as c where </span>[<span style="color: #0000ff">c.ISO3166.name</span>](http://c.ISO3166.name)<span style="color: #0000ff"> like "S%" and c.ISO3166.language="EN"</span>

![image](media://65679eea-8bf3-4d4b-beb0-eb4ebc410cd6)


## Fechas y horas

Puedes filtrar por fecha y hora con los operadores TIMESTAMP, TIME y DATE. Además, también puedes usar el operador DATEPART para seleccionar parte de una fecha, como el día.

**Nota:** Algunas bases de datos convierten automáticamente las cadenas de caracteres en fechas o en fechas y horas. SlamData no realiza esta conversión, ya que la base de datos subyacente no tiene un esquema ni un tipo fijo para ningún campo. Como resultado, una expresión como `WHERE ts > '2015-02-10'` compara los campos de valor cadena `ts` con la cadena `'2015-02-10'`, en lugar de hacer una comparación de fechas. Si quieres incluir fechas y marcas de tiempo literales en tus consultas SQL, debes utilizar los operadores de conversión de tiempo, que aceptan una cadena y devuelven un valor del tipo apropiado. Por ejemplo, el fragmento anterior podría convertirse en `WHERE ts > DATE '2015-02-10'`, que busca campos `ts` con valor de fecha y los compara con la fecha `2015-02-10`.

**Nota:** Si los datos de tu base de datos no utilizan un tipo nativo de fecha/hora, y en vez eso tú almacenas tus timestamp como milisegundos desde un epoch en un valor numérico, entonces debes comparar números o utilizar la función TO_TIMESTAMP.

**Filtro basado en una marca de tiempo (fecha y hora).**

Usael operador TIMESTAMP para convertir una cadena en una fecha y hora. La cadena debe tener el formato `YYYY-MM-DDTHH:MM:SS`.

<span style="color: #0000ff">select c.type,</span>[<span style="color: #0000ff">c.name</span>](http://c.name)<span style="color: #0000ff">,c.dateLastUpdate,DATE_PART("year",c.dateLastUpdate) as year from CLM_BusStop as c</span>

<span style="color: #0000ff">select c from CLM_BusStop as c WHERE c.CLM_BusStop.lastUpdateMillis > TO_TIMESTAMP(1446335999)</span>

<span style="color: #0000ff">select c from CLM_BusStop as c WHERE c.CLM_BusStop.lastUpdate > TIMESTAMP('2018-11-06T12:00:00.000Z')</span>


### Función NOW()

Esta función **devuelve la fecha actual del sistema**. Puedes usarla en el where de tus consultas para traer datos.

**<span style="color: #0000ff">NOW(“format“,'unitTime', amount)</span>**

- “**format**“: ("formato") le daremos el formato que necesitamos a la fecha, por ejemplo yyyy-MM-dd'T'HH: mm: ss'Z '"
- '**unitTime**': ('unidad de tiempo') para la echa, podemos aumentar o disminuir un número de horas, días, ... los valores posibles para 'unitTime' son: 'year', 'month', 'date', 'hour', 'minute', 'second','millisecond' (respectivamente: 'año', 'mes', 'fecha', 'hora', 'minuto', 'segundo ',' milisegundo')
- "**amount**": (cantidad) es un valor entero, positivo o negativo, que se suma o se resta en función de la unitTime seleccionada.

Ejemplos:

<span style="color: #0000ff">select * from MyOntology as c where c.date.timestamp>NOW()</span>

## Agrupación

SQL en Mongo te permite agrupar los datos por campos y por partes de la fecha.

**Agrupación en base a un solo campo.**

Usa GROUP BY para agrupar los resultados por un campo.

Ejemplo:

`SELECT c.age, COUNT(*) AS cnt
  FROM Users as c GROUP BY c.age`  


`SELECT c.age, c.gender, COUNT(*) AS cnt
  FROM Users as c GROUP BY c.age, c.gender`  


**Agrupación en base a parte de la fecha.**

Usa la función DATE_PART para agrupar por una parte de una fecha, como el mes.

Ejemplo:

`SELECT DATE_PART('day', c.ts) AS day, COUNT(*) AS cnt
  FROM Events as c
  GROUP BY DATE_PART('day', c.ts)`  


**Filtrado dentro de un grupo.**

Filtra los resultados dentro de un grupo añadiendo una cláusula HAVING seguida de un predicado booleano.

Ejemplo:

`SELECT DATE_PART('day', c.ts) AS day, COUNT(*) AS cnt
  FROM Events as c
  GROUP BY DATE_PART('day', c.ts)
  HAVING c.gender = 'female'`  


**Agrupación doble**

Realiza operaciones de agrupación doble poniendo operadores dentro de otros operadores. El operador interior se ejecutará sobre cada grupo creado por la cláusula GROUP BY, y el operador exterior se ejecutará sobre los resultados del operador interior.

Ejemplo:

Esta consulta devuelve la población media de los estados. La función externa de agregación (AVG; average o media) opera sobre los resultados de la agregación interna (SUM; suma) y la cláusula GROUP BY.

`SELECT AVG(SUM(p.pop)) FROM Population as p
  GROUP BY p.state`

## Datos anidados y matrices

A diferencia de las bases de datos relacionales, muchas bases de datos NoSQL permiten anidar datos (es decir, los datos pueden ser objetos) y contener matrices.

**Anidamiento**

El anidamiento se representa mediante niveles separados por un punto (.).

**Matrices**

Los elementos que son matrices (arrays) se representan con el índice de la matriz entre corchetes ([n]).

Ejemplo:

`SELECT c.profile.allAddress[0].street.number
  FROM Users as c`  


**Aplanamiento**

Puedes extraer todos los elementos de una matriz o todos los valores de los campos simultáneamente, eliminando esencialmente los niveles y aplanando los datos. Usa el asterisco entre corchetes ([*]) para extraer todos los elementos de la matriz.

Ejemplo:

`SELECT c.profile.allAddresses[*]
  FROM Users as c`  


Usa el asterisco entre llaves ({*}) para extraer todos los valores de los campos.

Ejemplo:

`SELECT c.profile.{*} FROM Users as c`  


**Filtrado mediante matrices**

Puedes filtrar utilizando los datos de todos los elementos de la matriz utilizando el asterisco entre corchetes ([*]) en una cláusula WHERE.

Ejemplo::

`SELECT DISTINCT * FROM Users as c
  WHERE c.profile.allAddresses[*].street.number = '221B'`

## Paginación y ordenación

**Paginación**

La paginación se utiliza para dividir los resultados grandes en trozos más pequeños. Usa el operador LIMIT para establecer el número de resultados a devolver y el operador OFFSET para establecer el índice en el que deben empezar los resultados.

Ejemplo (Limitar los resultados a 20 entradas):

`SELECT u FROM Users as u LIMIT 20`  


Ejemplo (Limitar los resultados a 20 entradas empezando en el 10):

`SELECT u FROM Users as u OFFSET 10 LIMIT 20`  


**Ordenación**

Usa la cláusula ORDER BY para ordenar los resultados. Puedes especificar uno o más campos para la ordenación y puedes utilizar operadores en los argumentos de ORDER BY. Usa ASC para ordenación ascendente y DESC para ordenación descendente.

Ejemplo (Ordenar los usuarios por edad ascendente):

`SELECT u 
  FROM Users as u
  ORDER BY u.age ASC`

## Joins

Usa el operador JOIN para unir diferentes colecciones.

Ejemplos:

Este ejemplo devuelve los nombres de los empleados y los nombres de los departamentos a los que pertenecen, haciendo coincidir el ID del departamento del empleado con el ID del departamento, donde ambos ID son de tipo ObjectID.

`SELECT emp.name, dept.name
  FROM Employee as emp
  JOIN Department as dept
  ON dept._id = emp.departmentId`

## Condicionales y nulos

**Condicionales**

Usa la expresión CASE para proporcionar lógica if-then-else a SQL². La sintaxis CASE es:

`SELECT (CASE <field>
  WHEN <value1> THEN <result1>
  WHEN <value2> THEN <result2>
  ...
  [ELSE <elseResult>
  END)
FROM "<path>"`

Ejemplo:

El siguiente ejemplo traduce los valores numéricos de la cadena a números reales.

<span style="color: #0000ff">select </span>

<span style="color: #0000ff">    (CASE c.Ticket.number </span>

<span style="color: #0000ff">      WHEN 'one' THEN 1 </span>

<span style="color: #0000ff">      WHEN 'two' THEN 2 </span>

<span style="color: #0000ff">      END) </span>

<span style="color: #0000ff">as nameParsed </span>

<span style="color: #0000ff">from Ticket as c</span>

## Consideraciones sobre el ID

MongoDB tiene reglas especiales sobre los campos llamados `_id`. Por ejemplo, deben ser únicos, lo que significa que algunas consultas (como `SELECT myarray[*] FROM foo`) introducirán duplicados que MongoDB no permitirá. Además, otras consultas cambian el valor de `_id` (como la agrupación).


**Para filtrar por ****_id****, **primero debes convertir una cadena en un objeto ID, utilizando la función `OID`. Por ejemplo:

<span style="color: #0000ff">SELECT * FROM Ticket WHERE _id = OID( 'abc123')</span>


Por defecto, el campo `_id` no aparecerá en un conjunto de resultados. Sin embargo, puedes especificarlo seleccionando el campo `_id`. Por ejemplo:

<span style="color: #0000ff">SELECT _id, u AS email FROM users as u</span>

## Consideraciones sobre el comodín *

Por razones de rendimiento, te recomendamos que evite usar el comodín '*' en los SELECT, y que lo sustituyas por proyecciones o campos explícitos:¡

<span style="color: #0000ff">SELECT * FROM Ticket  -> </span><span style="color: #0000ff">SELECT t FROM Ticket as t</span>

<span style="color: #0000ff">SELECT * FROM Ticket  -> </span><span style="color: #0000ff">SELECT t.Ticket.name as name, t.Ticket.number as number FROM Ticket as t</span>


## Ejemplos complejos

A continuación mostramos algunos ejemplos de consultas que hemos utilizado en diferentes proyectos:

`select `  
` t.tempo, e.lotto, count(1) `  
` from TempoDesc as t `  
` inner join `  
`   (select `  
`    c.lotto, c.epochEnd - d.minStart as durataTotale `  
`    from `  
`      (select `  
`        min(epochStart) as minStart, lotto `  
`        from Eventi1 `  
`        group by lotto) as d `  
`      inner join Eventi1 as c `  
`      on c.lotto=d.lotto ) as e `  
` on e.durataTotale <= t.tempo `  
` group by t.tempo, e.lotto`

`select `  
`      re.countrysrc,re.countrydest,re.count, iso.ISO3166.latitude , iso.ISO3166.longitude `  
`     from`  
`       ( select rx.routesexten.countrysrc as countrysrc, rx.routesexten.countrydest as countrydest, count(re.routesexten.countrysrc) as count `  
`from routesexten as rx `  
`group by rx.routesexten.countrysrc, rx.routesexten.countrydest `  
`order by count desc) as re `  
`     inner join `  
`        ISO3166_1 As iso on re.countrydest = iso.ISO3166.name`  
`     order by `  
`     re.count desc `  
`     limit 10`

# Operaciones de actualización (UPDATE)

  
También puedes realizar operaciones de actualización (UPDATE) en SQL. Aquí explicaremos las peculiaridades de este tipo de directivas SQL.

**Sintaxis simple**

Como en el SQL estándar, la directiva de actualización se construye de la siguiente manera:

<span style="color: #0000ff">UPDATE column SET attributes WHERE attributesFilter</span>


A continuación se muestran algunos ejemplos de operaciones básicas de Update:

Pongamos como ejemplo de trabajo la ontología de Restaurantes con la siguiente estructura:

![image](media://11c739eb-37ac-45f3-b2c1-f28171113c70)

<span style="color: #0000ff">update Restaurants set Restaurant.borough="Queens" where Restaurant.borough="Manhattan"</span>

![image](media://f4b1f938-e3ef-4dae-b58d-a8b4847f8c96)

<span style="color: #0000ff">update Restaurants set Restaurant.borough="Queens", Restaurant.restaurant_id=5400 where Restaurant.borough="Manhattan" and Restaurant.borough="Dj Reynolds Pub And Restaurant"</span>

## ObjectId

Si quieres filtrar por el ObjectId de Mongo, no necesitas usar ninguna función especial: basta con indicar el valor entre comillas del ObjectId, por ejemplo:

![image](media://ce1f7c77-22ce-4929-9887-712f63bd654c)

<span style="color: #0000ff">update Restaurants set Restaurant.borough="Manhattan", Restaurant.restaurant_id=5400 where _id="5d14883e29a91330a9625d0c"</span>

![image](media://65ad0bfe-ec23-45d6-88ed-032c3e2157da)

## ISODates

Como con el ObjectId, si quieres trabajar con fechas de Mongo, sólo tienes que poner el valor citado de la fecha en formato ISODate (yyyy-MM-dd'T'HH:mm:ss.SSS'Z'):

![image](media://ce765fe6-3e20-4646-9fda-04553846aac7)

<span style="color: #0000ff">update ThermometerData set ThermometerData.value=60 where ThermometerData.timestamp="2019-06-26T13:57:01.000Z"</span>

La consulta compilada:

![image](media://4447a279-0f7d-4fed-8ddd-170208bd9d6c)

 Resultado:

![image](media://53b12553-86fa-4d02-b339-3bb1e5ab6b6d)

## Booleanos

Si quieres establecer o filtrar valores booleanos, tienes que utilizar la función SQL Boolean() de este modo:

<span style="color: #0000ff">update ThermometerData set ThermometerData.bool=Boolean(true) where ThermometerData.timestamp="2019-06-26T13:57:01.000Z"</span>

![image](media://8603062c-0300-42c2-ac66-135264078735)

## Matrices

Si quieres añadir elementos a un campo matriz, tienes que utilizar la función APPEND().

APPEND(i, valor) acepta dos parámetros:

- i: Es opcional (por defecto es la última posición del array). Indica la posición en la que se va a introducir el valor.
- valor: Es el valor que se va a insertar en el array. Puede ser un objeto, una cadena, un número... Este parámetro puede ser también un array de valores.

Por ejemplo:

<span style="color: #0000ff">update ThermometerData set ThermometerData.array=APPEND("{\"Property\":\"value\"}")</span>

<span style="color: #0000ff">update ThermometerData set ThermometerData.array=APPEND([true, false])</span>

<span style="color: #0000ff">update ThermometerData set ThermometerData.array=APPEND([true, false, 45, "somestring", "2019-06-26T13:57:01.000Z"])</span>

El resultado es:

![image](media://87887738-2ff1-4fc2-9622-2d9cb7d86bb5)


**Nota importante:** Si quieres empujar un ISODate (fecha de Mongo) al array, querrás rodear el valor de isodate por una función ISODate:

<span style="color: #0000ff">update ThermometerData set ThermometerData.array=APPEND([true, false, 45, "somestring", ISODate("2019-06-26T13:57:01.000Z")])</span>

![image](media://b7738271-5b02-413c-ba8f-3004d67fbdbf)


# Operaciones de borrado (DELETE)

La directiva Delete funciona como en el SQL estándar.

<span style="color: #0000ff">DELETE FROM column WHERE attributes</span>

Las operaciones ObjectId, ISODate y Boolean funcionan como en las actualizaciones. Aún no se puede utilizar ningún tipo de operaciones de matrices en esta directiva.

Ejemplos:

<span style="color: #0000ff">DELETE FROM Restaurants WHERE _id="5d14883e29a91330a9625d0c"</span>

<span style="color: #0000ff">DELETE FROM Restaurants WHERE timestamp="2019-06-26T13:57:01.000Z"</span>

<span style="color: #0000ff">DELETE FROM Restaurants WHERE isClosed=Boolean(true)</span>




> Macro (__confluenceADFMigrationUnsupportedContentInternalExtension__)