Compartir a través de


Lenguaje de consulta de IoT Hub para dispositivos y módulos gemelos, trabajos y enrutamiento de mensajes

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:

  • una introducción a las características principales del lenguaje de consulta de IoT Hub y
  • una descripción más detallada del lenguaje. 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.

  1. Inicie sesión en Azure Portal y vaya a IoT Hub.
  2. Seleccione Consultas en la sección Administración de dispositivos del menú de navegación.
  3. 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 todas las consultas 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, LastActivityTime
    
  • Agregar los resultados de una consulta para devolver un recuento

    SELECT COUNT() as TotalNumber
    

Actualmente, las cláusulas de selección distintas a SELECT solo se admiten en las consultas agregadas de 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 en la colección FROM.

Cláusula FROM

La cláusula FROM <from_specification> es necesaria en todas las consultas 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 cláusula WHERE <condición_del_filtro> 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 que se incluya 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 cláusula GROUP BY<group_specification> 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

En la actualidad, el término group se trata en las consultas como si fuera una palabra clave especial. 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 en 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(string, start [, length]) 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.
ENDS_WITH(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#

El SDK del servicio Azure IoT Hub para .NET expone la funcionalidad de consulta 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 haciendo múltiples llamadas a los métodos GetNextAsTwinAsync.

Ejemplo de Node.js

El SDK del servicio Azure IoT Hub expone la funcionalidad de consulta para Node.jsen 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. Después, se recuperan diversas páginas con varias llamadas al método nextAsTwin.

Pasos siguientes