Analisar dados JSON e Avro no Azure Stream Analytics

O Azure Stream Analytics suporta o processamento de eventos em formatos de dados CSV, JSON e Avro. Os dados JSON e Avro podem ser estruturados e conter alguns tipos complexos, como objetos aninhados (registos) e matrizes.

Nota

Os ficheiros AVRO criados pela Captura do Hub de Eventos utilizam um formato específico que requer que utilize a funcionalidade de desserializador personalizado . Para obter mais informações, veja Read input in any format using .NET custom deserializers (Ler entradas em qualquer formato com desseriais personalizados .NET).

Tipos de dados de registo

Os tipos de dados de registo são utilizados para representar matrizes JSON e Avro quando os formatos correspondentes são utilizados nos fluxos de dados de entrada. Estes exemplos demonstram um sensor de exemplo, que está a ler eventos de entrada no formato JSON. Eis um exemplo de um único evento:

{
    "DeviceId" : "12345",
    "Location" :
    {
        "Lat": 47,
        "Long": 122
    },
    "SensorReadings" :
    {
        "Temperature" : 80,
        "Humidity" : 70,
        "CustomSensor01" : 5,
        "CustomSensor02" : 99,
        "SensorMetadata" : 
        {
        "Manufacturer":"ABC",
        "Version":"1.2.45"
        }
    }
}

Aceder a campos aninhados no esquema conhecido

Utilize a notação de pontos (.) para aceder facilmente a campos aninhados diretamente a partir da consulta. Por exemplo, esta consulta seleciona as coordenadas Latitude e Longitude na propriedade Localização nos dados JSON anteriores. A notação de pontos pode ser utilizada para navegar por vários níveis, conforme mostrado abaixo.

SELECT
    DeviceID,
    Location.Lat,
    Location.Long,
    SensorReadings.Temperature,
    SensorReadings.SensorMetadata.Version
FROM input

O resultado é:

DeviceID Lat Longo Temperatura Versão
12345 47 122 80 1.2.45

Selecionar todas as propriedades

Pode selecionar todas as propriedades de um registo aninhado com o caráter universal "*". Considere o exemplo seguinte:

SELECT
    DeviceID,
    Location.*
FROM input

O resultado é:

DeviceID Lat Longo
12345 47 122

Aceder a campos aninhados quando o nome da propriedade é uma variável

Utilize a função GetRecordPropertyValue se o nome da propriedade for uma variável. Isto permite criar consultas dinâmicas sem nomes de propriedades de codificação.

Por exemplo, imagine que o fluxo de dados de exemplo tem de ser associado a dados de referência que contenham limiares para cada sensor de dispositivo. Abaixo, é apresentado um fragmento desses dados de referência.

{
    "DeviceId" : "12345",
    "SensorName" : "Temperature",
    "Value" : 85
},
{
    "DeviceId" : "12345",
    "SensorName" : "Humidity",
    "Value" : 65
}

O objetivo aqui é associar o nosso conjunto de dados de exemplo da parte superior do artigo a esses dados de referência e produzir um evento para cada medida de sensor acima do limiar. Isto significa que o nosso único evento acima pode gerar vários eventos de saída se vários sensores estiverem acima dos respetivos limiares, graças à associação. Para obter resultados semelhantes sem uma associação, veja a secção abaixo.

SELECT
    input.DeviceID,
    thresholds.SensorName,
    "Alert: Sensor above threshold" AS AlertMessage
FROM input      -- stream input
JOIN thresholds -- reference data input
ON
    input.DeviceId = thresholds.DeviceId
WHERE
    GetRecordPropertyValue(input.SensorReadings, thresholds.SensorName) > thresholds.Value

GetRecordPropertyValue seleciona a propriedade em SensorReadings, que nome corresponde ao nome da propriedade proveniente dos dados de referência. Em seguida, o valor associado do SensorReadings é extraído.

O resultado é:

DeviceID SensorName AlertMessage
12345 Humidade Alerta: Sensor acima do limiar

Converter campos de registo em eventos separados

Para converter campos de registo em eventos separados, utilize o operador APPLY juntamente com a função GetRecordProperties .

Com os dados de exemplo originais, a seguinte consulta pode ser utilizada para extrair propriedades para diferentes eventos.

SELECT
    event.DeviceID,
    sensorReading.PropertyName,
    sensorReading.PropertyValue
FROM input as event
CROSS APPLY GetRecordProperties(event.SensorReadings) AS sensorReading

O resultado é:

DeviceID SensorName AlertMessage
12345 Temperatura 80
12345 Humidade 70
12345 CustomSensor01 5
12345 CustomSensor02 99
12345 SensorMetadata [objeto objeto]

Ao utilizar o WITH, é possível encaminhar esses eventos para diferentes destinos:

WITH Stage0 AS
(
    SELECT
        event.DeviceID,
        sensorReading.PropertyName,
        sensorReading.PropertyValue
    FROM input as event
    CROSS APPLY GetRecordProperties(event.SensorReadings) AS sensorReading
)

SELECT DeviceID, PropertyValue AS Temperature INTO TemperatureOutput FROM Stage0 WHERE PropertyName = 'Temperature'
SELECT DeviceID, PropertyValue AS Humidity INTO HumidityOutput FROM Stage0 WHERE PropertyName = 'Humidity'

Analisar o registo JSON nos dados de referência do SQL

Ao utilizar SQL do Azure Base de Dados como dados de referência na sua tarefa, é possível ter uma coluna com dados no formato JSON. Apresentamos um exemplo abaixo.

DeviceID Dados
12345 {"key": "value1"}
54321 {"key": "value2"}

Pode analisar o registo JSON na coluna Dados ao escrever uma função simples definida pelo utilizador javaScript.

function parseJson(string) {
return JSON.parse(string);
}

Em seguida, pode criar um passo na consulta do Stream Analytics, conforme mostrado abaixo, para aceder aos campos dos seus registos JSON.

WITH parseJson as
(
SELECT DeviceID, udf.parseJson(sqlRefInput.Data) as metadata,
FROM sqlRefInput
)

SELECT metadata.key
INTO output
FROM streamInput
JOIN parseJson 
ON streamInput.DeviceID = parseJson.DeviceID

Tipos de dados de matriz

Os tipos de dados de matriz são uma coleção ordenada de valores. Algumas operações típicas em valores de matriz são detalhadas abaixo. Estes exemplos utilizam as funções GetArrayElement, GetArrayElements, GetArrayLength e o operador APPLY .

Eis um exemplo de um evento. Ambos CustomSensor03 e SensorMetadata são de matriz de tipo:

{
    "DeviceId" : "12345",
    "SensorReadings" :
    {
        "Temperature" : 80,
        "Humidity" : 70,
        "CustomSensor01" : 5,
        "CustomSensor02" : 99,
        "CustomSensor03": [12,-5,0]
     },
    "SensorMetadata":[
        {          
            "smKey":"Manufacturer",
            "smValue":"ABC"                
        },
        {
            "smKey":"Version",
            "smValue":"1.2.45"
        }
    ]
}

Trabalhar com um elemento de matriz específico

Selecione o elemento de matriz num índice especificado (selecionando o primeiro elemento de matriz):

SELECT
    GetArrayElement(SensorReadings.CustomSensor03, 0) AS firstElement
FROM input

O resultado é:

firstElement
12

Selecionar comprimento da matriz

SELECT
    GetArrayLength(SensorReadings.CustomSensor03) AS arrayLength
FROM input

O resultado é:

matrizLength
3

Converter elementos de matriz em eventos separados

Selecione todo o elemento de matriz como eventos individuais. O operador APPLY juntamente com a função incorporada GetArrayElements extrai todos os elementos de matriz como eventos individuais:

SELECT
    DeviceId,
	CustomSensor03Record.ArrayIndex,
	CustomSensor03Record.ArrayValue
FROM input
CROSS APPLY GetArrayElements(SensorReadings.CustomSensor03) AS CustomSensor03Record

O resultado é:

DeviceId MatrizIndex ArrayValue
12345 0 12
12345 1 -5
12345 2 0
SELECT   
    i.DeviceId,	
    SensorMetadataRecords.ArrayValue.smKey as smKey,
    SensorMetadataRecords.ArrayValue.smValue as smValue
FROM input i
CROSS APPLY GetArrayElements(SensorMetadata) AS SensorMetadataRecords

O resultado é:

DeviceId smKey smValue
12345 Fabricante ABC
12345 Versão 1.2.45

Se os campos extraídos precisarem de aparecer em colunas, é possível dinamizar o conjunto de dados com a sintaxe WITH para além da operação JOIN . Essa associação requer uma condição de limite de tempo que impede a duplicação:

WITH DynamicCTE AS (
	SELECT   
		i.DeviceId,
		SensorMetadataRecords.ArrayValue.smKey as smKey,
		SensorMetadataRecords.ArrayValue.smValue as smValue
	FROM input i
	CROSS APPLY GetArrayElements(SensorMetadata) AS SensorMetadataRecords 
)

SELECT
	i.DeviceId,
	i.Location.*,
	V.smValue AS 'smVersion',
	M.smValue AS 'smManufacturer'
FROM input i
LEFT JOIN DynamicCTE V ON V.smKey = 'Version' and V.DeviceId = i.DeviceId AND DATEDIFF(minute,i,V) BETWEEN 0 AND 0 
LEFT JOIN DynamicCTE M ON M.smKey = 'Manufacturer' and M.DeviceId = i.DeviceId AND DATEDIFF(minute,i,M) BETWEEN 0 AND 0

O resultado é:

DeviceId Lat Longo smVersion smManufacturer
12345 47 122 1.2.45 ABC

Consulte também

Tipos de Dados no Azure Stream Analytics