Nota
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
IoT Hub proporciona un lenguaje eficaz de tipo SQL para recuperar información con respecto a los dispositivos gemelos, módulos gemelos, trabajos y enrutamiento de mensajes. Este artículo presenta:
- Introducción a las características principales del lenguaje de consulta IoT Hub.
- Descripción detallada del idioma. Para más información sobre el lenguaje de consulta para el enrutamiento de mensajes, consulte Sintaxis de consulta de enrutamiento de mensajes de IoT Hub.
Para obtener ejemplos específicos, consulte Consultas para dispositivos y módulos gemelos de IoT Hub o Consultas para trabajos de IoT Hub.
Nota
Algunas de las características que se mencionan en este artículo, como la mensajería de la nube al dispositivo, los dispositivos gemelos y la administración de dispositivos, solo están disponibles en el nivel estándar de IoT Hub. Para obtener más información sobre los niveles Básico y Estándar/Gratuito de IoT Hub, consulte Elegir el nivel y tamaño de IoT Hub adecuado para su solución.
Ejecutar consultas de IoT Hub
Puedes ejecutar consultas directamente en tu IoT hub en el portal de Azure.
- Inicie sesión en Azure Portal y vaya a IoT Hub.
- Seleccione Consultas en la sección Administración de dispositivos del menú de navegación.
- Escriba una consulta en el cuadro de texto y seleccione Ejecutar consulta.
También puede ejecutar consultas en las aplicaciones mediante las API de servicio y SDK de servicios IoT de Azure.
Para ejemplos de código que implementan consultas de IoT Hub, consulte la sección Ejemplos de consultas con los SDK de servicio.
Para ver vínculos a las páginas de referencia del SDK y ejemplos, consulte SDK de Azure IoT Hub.
Conceptos básicos de una consulta de IoT Hub
Cada consulta de IoT Hub consta de las cláusulas SELECT y FROM, además de las cláusulas opcionales WHERE y GROUP BY.
Las consultas se ejecutan en una colección de documentos JSON, por ejemplo, dispositivos gemelos. La cláusula FROM indica la colección de documentos sobre la que se va a iterar (devices, devices.modules o devices.jobs).
Después se aplica el filtro en la cláusula WHERE. Con agregaciones, los resultados de este paso se agrupan según se especifique en la cláusula GROUP BY. Para cada grupo, se genera una fila de acuerdo con lo especificado en la cláusula SELECT.
SELECT <select_list>
FROM <from_specification>
[WHERE <filter_condition>]
[GROUP BY <group_specification>]
Cláusula SELECT
La cláusula SELECT <select_list> es necesaria en cada consulta IoT Hub. Especifica qué valores se recuperan de la consulta. Especifica los valores JSON que se usarán para generar nuevos objetos JSON.
Para cada elemento del subconjunto filtrado (y, opcionalmente, agrupado) de la colección FROM, la fase de proyección genera un nuevo objeto JSON. Este objeto se construye con los valores especificados en la cláusula SELECT.
Por ejemplo:
Devolver todos los valores
SELECT *Devolver propiedades específicas
SELECT DeviceID, LastActivityTimeAgregar los resultados de una consulta para devolver un recuento
SELECT COUNT() as TotalNumber
Actualmente, las cláusulas de selección diferentes a SELECT solo se admiten en consultas agregadas en dispositivos gemelos.
La sintaxis siguiente es la gramática de la cláusula SELECT:
SELECT [TOP <max number>] <projection list>
<projection_list> ::=
'*'
| <projection_element> AS alias [, <projection_element> AS alias]+
<projection_element> :==
attribute_name
| <projection_element> '.' attribute_name
| <aggregate>
<aggregate> :==
count()
| avg(<projection_element>)
| sum(<projection_element>)
| min(<projection_element>)
| max(<projection_element>)
Attribute_name hace referencia a cualquier propiedad del documento JSON de la colección FROM.
Cláusula FROM
La FROM <from_specification> cláusula es necesaria en cada consulta de ioT Hub. Debe ser uno de estos tres valores:
- dispositivos para consultar dispositivos gemelos
- devices.modules para consultar módulos gemelos
- devices.jobs para consultar los detalles del trabajo por dispositivo
Por ejemplo:
Recuperación de todos los dispositivos gemelos
SELECT * FROM devices
Cláusula WHERE
La WHERE <filter_condition> cláusula es opcional. Especifica una o varias condiciones que los documentos JSON en la colección FROM deben satisfacer para incluirse como parte del resultado. Cualquier documento JSON debe evaluar las condiciones especificadas como true para ser incluido en el resultado.
Por ejemplo:
Recuperación de todos los trabajos que tienen como destino un dispositivo específico
SELECT * FROM devices.jobs WHERE devices.jobs.deviceId = 'myDeviceId'
Las condiciones permitidas se describen en la sección Expresiones y condiciones .
Cláusula GROUP BY
La GROUP BY <group_specification> cláusula es opcional. Esta cláusula se ejecuta después del filtro especificado en la cláusula WHERE y antes de la proyección especificada en la cláusula SELECT. Agrupa los documentos según el valor de un atributo. Estos grupos se usan para generar valores agregados, como se especifica en la cláusula SELECT.
Por ejemplo:
Devolución del recuento de dispositivos que notifican todos los estados de configuración de telemetría
SELECT properties.reported.telemetryConfig.status AS status, COUNT() AS numberOfDevices FROM devices GROUP BY properties.reported.telemetryConfig.status
Actualmente, solo se admite la cláusula GROUP BY al consultar dispositivos gemelos.
Precaución
El término grupo se trata actualmente como una palabra clave especial en las consultas. En caso de que use group como nombre de propiedad, considere la posibilidad de rodearlo con corchetes dobles para evitar errores, como se muestra en este ejemplo: SELECT * FROM devices WHERE tags.[[group]].name = 'some_value'.
La sintaxis formal de GROUP BY es:
GROUP BY <group_by_element>
<group_by_element> :==
attribute_name
| < group_by_element > '.' attribute_name
Attribute_name hace referencia a cualquier propiedad del documento JSON de la colección FROM.
Paginación de resultados de la consulta
Se crea una instancia de un objeto de consulta con un tamaño máximo de página menor o igual que 100 registros. Para obtener varias páginas, llame varias veces a nextAsTwin en el SDK de Node.js o a GetNextAsTwinAsync en el SDK de .NET. El objeto de consulta puede exponer varios valores Next, en función de la opción de deserialización que requiera la consulta. Por ejemplo, un objeto de consulta puede devolver objetos de trabajo o dispositivos gemelos, o JSON sin formato si se usan proyecciones.
Expresiones y condiciones
En un nivel general, una expresión:
- Se evalúa como una instancia de tipo JSON (como booleano, número, cadena, matriz u objeto).
- Se define manipulando datos procedentes del documento JSON del dispositivo y constantes mediante funciones y operadores integrados.
Las condiciones son expresiones que se evalúan como un valor booleano. Cualquier constante distinta al booleano true se considera como false. Esta regla incluye null, undefined, cualquier instancia de objeto o matriz, cualquier cadena y el valor booleano false.
La sintaxis de las expresiones es:
<expression> ::=
<constant> |
attribute_name |
<function_call> |
<expression> binary_operator <expression> |
<create_array_expression> |
'(' <expression> ')'
<function_call> ::=
<function_name> '(' expression ')'
<constant> ::=
<undefined_constant>
| <null_constant>
| <number_constant>
| <string_constant>
| <array_constant>
<undefined_constant> ::= undefined
<null_constant> ::= null
<number_constant> ::= decimal_literal | hexadecimal_literal
<string_constant> ::= string_literal
<array_constant> ::= '[' <constant> [, <constant>]+ ']'
Para comprender lo que significa cada símbolo en la sintaxis de expresiones, consulte la tabla siguiente:
| Símbolo | Definición |
|---|---|
| nombre_del_atributo | Cualquier propiedad del documento JSON en la colección FROM. |
| operador binario | Cualquier operador binario que figure en la sección Operadores. |
| function_name | Cualquier función que figure en la sección Funciones. |
| decimal_literal | Un número flotante expresado en notación decimal. |
| hexadecimal_literal | Un número expresado por la cadena "0x" seguido de una cadena de dígitos hexadecimales. |
| string_literal | Las cadenas Unicode representadas por una secuencia de cero o varios caracteres Unicode o secuencias de escape. Los literales de cadena se cierran entre comillas simples o dobles. Caracteres de escape permitidos: \', \", \\, \uXXXX para los caracteres Unicode definidos con cuatro dígitos hexadecimales. |
Operadores
Se admiten los siguientes operadores:
| Familia | Operadores |
|---|---|
| Aritmética | +, -, *, /, % |
| Lógicos | Y, O, NO |
| Comparación | =, !=, <, >, <, >=, <> |
Funciones
Cuando se consultan gemelos y trabajos, la única función admitida es:
| Función | Descripción |
|---|---|
| IS_DEFINED(property) | Devuelve un valor booleano que indica si a la propiedad se le asigna un valor (incluido null). |
En condiciones de rutas, se admiten las siguientes funciones matemáticas:
| Función | Descripción |
|---|---|
| ABS(x) | Devuelve el valor absoluto (positivo) de la expresión numérica especificada. |
| EXP(x) | Devuelve el valor exponencial de la expresión numérica especificada (e^x). |
| POTENCIA(x,y) | Devuelve el valor de la expresión especificada a la potencia especificada (x^y). |
| SQUARE(x) | Devuelve el cuadrado del valor numérico especificado. |
| CEILING(x) | Devuelve el valor entero más pequeño mayor o igual que la expresión numérica especificada. |
| FLOOR(x) | Devuelve el entero más grande que sea menor o igual que la expresión numérica especificada. |
| SIGN(x) | Devuelve el signo positivo (+1), cero (0) o negativo (-1) de la expresión numérica especificada. |
| SQRT(x) | Devuelve la raíz cuadrada del valor numérico especificado. |
En condiciones de rutas, se admiten las funciones de conversión y comprobación de tipos siguientes:
| Función | Descripción |
|---|---|
| AS_NUMBER | Convierte la cadena de entrada en un número.
noop si la entrada es un número; Undefined si la cadena no representa un número. |
| IS_ARRAY | Devuelve un valor booleano que indica si el tipo de la expresión especificada es una matriz. |
| IS_BOOL | Devuelve un valor booleano que indica si el tipo de la expresión especificada es un valor booleano. |
| IS_DEFINED | Devuelve un valor booleano que indica si la propiedad es un valor. Esta función solo se admite cuando el valor es de tipo primitivo. Los tipos primitivos son cadena, booleano, numérico o null. No se admiten dateTime, tipos de objeto y matrices. |
| IS_NULL | Devuelve un valor booleano que indica si el tipo de la expresión especificada es nulo. |
| IS_NUMBER | Devuelve un valor booleano que indica si el tipo de la expresión especificada es un número. |
| IS_OBJECT | Devuelve un valor booleano que indica si el tipo de la expresión especificada es un objeto JSON. |
| IS_PRIMITIVE | Devuelve un valor booleano que indica si el tipo de la expresión especificada es un tipo primitivo (cadena, booleano, numérico o null). |
| IS_STRING | Devuelve un valor booleano que indica si el tipo de la expresión especificada es una cadena. |
En condiciones de rutas, se admiten las siguientes funciones de cadena:
| Función | Descripción |
|---|---|
| CONCAT(x, y, ...) | Devuelve una cadena que es el resultado de concatenar dos o más valores de cadena. |
| LENGTH(x) | Devuelve el número de caracteres de la expresión de cadena especificada. |
| LOWER(x) | Devuelve una expresión de cadena después de convertir los datos de caracteres en mayúsculas a minúsculas. |
| UPPER(x) | Devuelve una expresión de cadena después de convertir datos de caracteres en minúsculas a mayúsculas. |
| SUBSTRING(cadena, inicio [, longitud]) | Devuelve parte de una expresión de cadena a partir de la posición de base cero del carácter especificado y continúa hasta la longitud especificada, o hasta el final de la cadena. |
| INDEX_OF(string, fragment) | Devuelve la posición inicial de la primera aparición de la expresión de la segunda cadena dentro de la primera expresión de cadena especificada, o -1 si no se encuentra la cadena. |
| EMPIEZA_CON(x, y) | Devuelve un valor booleano que indica si la primera expresión de cadena empieza con la segunda. |
| TERMINA_CON(x, y) | Devuelve un valor booleano que indica si la primera expresión de cadena finaliza con la segunda. |
| CONTAINS(x,y) | Devuelve un valor booleano que indica si la primera expresión de cadena contiene la segunda. |
Ejemplos de consultas con los SDK de servicio
Ejemplo de C#
La funcionalidad de consulta se expone mediante el SDK del servicio Azure IoT Hub para .NET en la clase RegistryManager.
Este ejemplo se corresponde a una consulta simple:
var query = registryManager.CreateQuery("SELECT * FROM devices", 100);
while (query.HasMoreResults)
{
var page = await query.GetNextAsTwinAsync();
foreach (var twin in page)
{
// do work on twin object
}
}
Se crea una instancia del objeto de consulta con los parámetros mencionados en la sección Paginación de resultados de la consulta. Se recuperan varias páginas llamando a los GetNextAsTwinAsync métodos varias veces.
Ejemplo de Node.js
El SDK del servicio Azure IoT Hub expone la funcionalidad de consulta para Node.js en el objeto Registry.
Este ejemplo se corresponde a una consulta simple:
var query = registry.createQuery('SELECT * FROM devices', 100);
var onResults = function(err, results) {
if (err) {
console.error('Failed to fetch the results: ' + err.message);
} else {
// Do something with the results
results.forEach(function(twin) {
console.log(twin.deviceId);
});
if (query.hasMoreResults) {
query.nextAsTwin(onResults);
}
}
};
query.nextAsTwin(onResults);
Se crea una instancia del objeto de consulta con los parámetros mencionados en la sección Paginación de resultados de la consulta. Varias páginas se recuperan llamando al nextAsTwin método varias veces.
Consultas para dispositivos y módulos gemelos de IoT Hub
Los dispositivos gemelos y módulos gemelos pueden contener objetos JSON arbitrarios como etiquetas y propiedades. IoT Hub permite consultar dispositivos gemelos y módulos gemelos como un único documento JSON que contiene toda la información del gemelo.
Este es un dispositivo gemelo de IoT Hub de ejemplo (el módulo gemelo sería similar solo con un parámetro para moduleId):
{
"deviceId": "myDeviceId",
"etag": "AAAAAAAAAAc=",
"status": "enabled",
"statusUpdateTime": "0001-01-01T00:00:00",
"connectionState": "Disconnected",
"lastActivityTime": "0001-01-01T00:00:00",
"cloudToDeviceMessageCount": 0,
"authenticationType": "sas",
"x509Thumbprint": {
"primaryThumbprint": null,
"secondaryThumbprint": null
},
"version": 2,
"tags": {
"location": {
"region": "US",
"plant": "Redmond43"
}
},
"properties": {
"desired": {
"telemetryConfig": {
"configId": "db00ebf5-eeeb-42be-86a1-458cccb69e57",
"sendFrequencyInSecs": 300
},
"$metadata": {
...
},
"$version": 4
},
"reported": {
"connectivity": {
"type": "cellular"
},
"telemetryConfig": {
"configId": "db00ebf5-eeeb-42be-86a1-458cccb69e57",
"sendFrequencyInSecs": 300,
"status": "Success"
},
"$metadata": {
...
},
"$version": 7
}
}
}
Consultas de dispositivos gemelos
IoT Hub expone los dispositivos gemelos como una colección de documentos denominada dispositivos. Por ejemplo, la consulta más básica recupera todo el conjunto de dispositivos gemelos:
SELECT * FROM devices
Nota
Azure IoT SDKs admiten la paginación de resultados grandes.
Puede agregar los resultados de una consulta mediante la cláusula SELECT. Por ejemplo, la consulta siguiente obtiene un recuento del número total de dispositivos de un centro de IoT:
SELECT COUNT() as totalNumberOfDevices FROM devices
Filtre los resultados de la consulta mediante la cláusula WHERE. Por ejemplo, para recibir dispositivos gemelos en los que la location.region etiqueta está establecida en EE. UU ., use la consulta siguiente:
SELECT * FROM devices
WHERE tags.location.region = 'US'
Cree cláusulas WHERE complejas mediante operadores booleanos y comparaciones aritméticas. Por ejemplo, la consulta siguiente recupera dispositivos gemelos ubicados en EE. UU. y configurados para enviar telemetría menos de cada minuto:
SELECT * FROM devices
WHERE tags.location.region = 'US'
AND properties.reported.telemetryConfig.sendFrequencyInSecs >= 60
También puede usar constantes de matriz con los operadores IN y NIN (no está en). Por ejemplo, la consulta siguiente recupera dispositivos gemelos que notifican conectividad WiFi o cableada:
SELECT * FROM devices
WHERE properties.reported.connectivity IN ['wired', 'wifi']
A menudo es necesario identificar todos los dispositivos gemelos que contienen una propiedad específica. IoT Hub admite la función is_defined() para este fin. Por ejemplo, la consulta siguiente recupera dispositivos gemelos que definen la connectivity propiedad :
SELECT * FROM devices
WHERE is_defined(properties.reported.connectivity)
Consulte la sección cláusula WHERE para obtener la referencia completa de las funcionalidades de filtrado.
También se admite la agrupación. Por ejemplo, la consulta siguiente devuelve el recuento de dispositivos en cada estado de configuración de telemetría:
SELECT properties.reported.telemetryConfig.status AS status,
COUNT() AS numberOfDevices
FROM devices
GROUP BY properties.reported.telemetryConfig.status
Esta consulta de agrupación devolvería un resultado similar al ejemplo siguiente:
[
{
"numberOfDevices": 3,
"status": "Success"
},
{
"numberOfDevices": 2,
"status": "Pending"
},
{
"numberOfDevices": 1,
"status": "Error"
}
]
En este ejemplo, tres dispositivos notificaron una configuración correcta, dos siguen aplicando la configuración y uno notificó un error.
Las consultas de proyección permiten a los desarrolladores retornar únicamente las propiedades que les interesan. Por ejemplo, para recuperar la hora de la última actividad junto con el identificador de dispositivo de todos los dispositivos habilitados que están desconectados, use la consulta siguiente:
SELECT DeviceId, LastActivityTime FROM devices WHERE status = 'enabled' AND connectionState = 'Disconnected'
El resultado de esa consulta sería similar al ejemplo siguiente:
[
{
"deviceId": "AZ3166Device",
"lastActivityTime": "2021-05-07T00:50:38.0543092Z"
}
]
Consultas de módulos duplicados
La consulta en módulos gemelos es similar a la consulta en dispositivos gemelos, pero usando una colección o un espacio de nombres diferente; en lugar de desde devices, se consulta desde devices.modules:
SELECT * FROM devices.modules
No se permite la unión entre los dispositivos y las colecciones devices.modules. Si desea consultar módulos gemelos entre dispositivos, lo hace en función de las etiquetas. La consulta siguiente devuelve todos los módulos gemelos en todos los dispositivos con el estado de examen:
SELECT * FROM devices.modules WHERE properties.reported.status = 'scanning'
La consulta siguiente devuelve todos los módulos gemelos con el estado de examen, pero solo en el subconjunto especificado de dispositivos:
SELECT * FROM devices.modules
WHERE properties.reported.status = 'scanning'
AND deviceId IN ['device1', 'device2']
Limitaciones de las consultas gemelas
Importante
Los resultados de la consulta son operaciones coherentes y los retrasos de hasta 30 minutos deben tolerarse. En la mayoría de los casos, la consulta gemela devuelve resultados en el orden de unos segundos. IoT Hub se esfuerza por proporcionar una latencia baja para todas las operaciones. Sin embargo, debido a las condiciones de la red y otros factores impredecibles, no puede garantizar una latencia determinada.
Una opción alternativa a las consultas gemelas es consultar dispositivos gemelos individuales por identificador mediante la API REST get twin. Esta API siempre devuelve los valores más recientes y tiene límites de limitación más altos. Puede emitir la API REST directamente o usar la funcionalidad equivalente en uno de los SDK de servicio de Azure IoT Hub.
Las expresiones de consulta pueden tener una longitud máxima de 8192 caracteres.
Actualmente, las comparaciones solo se admiten entre tipos primitivos (sin objetos), por ejemplo ... WHERE properties.desired.config = properties.reported.config solo se admite si esas propiedades tienen valores primitivos.
Se recomienda no depender de lastActivityTime encontrado en las Propiedades de Identidad del Dispositivo para Consultas Gemelas en cualquier escenario. Este campo no garantiza un medidor preciso del estado del dispositivo. En su lugar, use eventos de ciclo de vida de dispositivos IoT para administrar el estado y las actividades del dispositivo. Para obtener información sobre cómo usar eventos de ciclo de vida de IoT Hub en tu solución, consulta Reacciona a los eventos de IoT Hub usando Event Grid para desencadenar acciones.
Nota
Evite realizar suposiciones sobre la latencia máxima de esta operación. Consulte Soluciones de latencia para obtener más información sobre cómo crear la solución teniendo en cuenta la latencia.
Consultas para trabajos en IoT Hub
Los trabajos proporcionan una manera de ejecutar operaciones en conjuntos de dispositivos. Cada dispositivo gemelo contiene la información de los trabajos que lo tienen como destino en una colección denominada trabajos. IoT Hub permite consultar trabajos como un único documento JSON que contiene toda la información del gemelo.
Este es un dispositivo gemelo de IoT Hub de ejemplo que forma parte de un trabajo denominado myJobId:
{
"deviceId": "myDeviceId",
"etag": "AAAAAAAAAAc=",
"tags": {
...
},
"properties": {
...
},
"jobs": [
{
"deviceId": "myDeviceId",
"jobId": "myJobId",
"jobType": "scheduleUpdateTwin",
"status": "completed",
"startTimeUtc": "2016-09-29T18:18:52.7418462",
"endTimeUtc": "2016-09-29T18:20:52.7418462",
"createdDateTimeUtc": "2016-09-29T18:18:56.7787107Z",
"lastUpdatedDateTimeUtc": "2016-09-29T18:18:56.8894408Z",
"outcome": {
"deviceMethodResponse": null
}
},
...
]
}
Actualmente, esta colección se puede consultar como devices.jobs en el lenguaje de consulta de IoT Hub.
Importante
Actualmente, la propiedad jobs no se devuelve al consultar dispositivos gemelos. Es decir, las consultas que contienen FROM devices. Solo se puede acceder a la propiedad jobs directamente con consultas mediante FROM devices.jobs.
Por ejemplo, la consulta siguiente devuelve todos los trabajos (pasados y programados) que afectan a un único dispositivo:
SELECT * FROM devices.jobs
WHERE devices.jobs.deviceId = 'myDeviceId'
Tenga en cuenta cómo esta consulta proporciona el estado específico del dispositivo (y posiblemente la respuesta del método directo) de cada trabajo devuelto.
También es posible filtrar con condiciones booleanas arbitrarias en todas las propiedades de objeto de la devices.jobs colección.
Por ejemplo, la consulta siguiente recupera todos los trabajos de actualización de dispositivos gemelos completados creados después de septiembre de 2016 para un dispositivo específico:
SELECT * FROM devices.jobs
WHERE devices.jobs.deviceId = 'myDeviceId'
AND devices.jobs.jobType = 'scheduleUpdateTwin'
AND devices.jobs.status = 'completed'
AND devices.jobs.createdTimeUtc > '2016-09-01'
También puede recuperar los resultados por dispositivo de un solo trabajo.
SELECT * FROM devices.jobs
WHERE devices.jobs.jobId = 'myJobId'
Limitaciones de la consulta de trabajos
Las expresiones de consulta pueden tener una longitud máxima de 8192 caracteres.
Actualmente, las consultas en devices.jobs no admiten:
- Las proyecciones, por lo tanto, solo son posibles
SELECT *. - Condiciones que hacen referencia al dispositivo gemelo además de las propiedades del trabajo (consulte la sección anterior).
- Agregaciones, como count, avg y group by.
Contenido relacionado
- Obtenga más información sobre el enrutamiento de mensajes en función de las propiedades del mensaje o el cuerpo del mensaje con la Sintaxis de las consultas de enrutamiento de mensajes de IoT Hub.