Partilhar via


Analisar dados JSON e Avro no Azure Stream Analytics

O serviço Azure Stream Analytics dá suporte ao processamento de eventos nos formatos de dados CSV, JSON e Avro. Os dados JSON e Avro podem ser estruturados e conter alguns tipos complexos, como objetos aninhados (registros) e matrizes.

Nota

Os arquivos AVRO criados pelo Event Hubs Capture usam um formato específico que requer que você use o recurso de desserializador personalizado. Para obter mais informações, consulte Ler entrada em qualquer formato usando desserializadores personalizados do .NET.

Tipos de dados de registo

Os tipos de dados de registro são usados para representar matrizes JSON e Avro quando os formatos correspondentes são usados nos fluxos de dados de entrada. Estes exemplos demonstram um sensor de exemplo, que está lendo 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"
        }
    }
}

Acessar campos aninhados no esquema conhecido

Use a notação de pontos (.) para acessar facilmente campos aninhados diretamente da sua consulta. Por exemplo, essa consulta seleciona as coordenadas Latitude e Longitude na propriedade Location nos dados JSON anteriores. A notação de pontos pode ser usada para navegar em vários níveis, conforme mostrado no seguinte trecho:

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

O resultado é:

ID do dispositivo Lat Longo Temperatura Versão
12345 47 122 80 1.2.45

Selecionar todas as propriedades

Você pode selecionar todas as propriedades de um registro aninhado usando o curinga '*'. Considere o seguinte exemplo:

SELECT
    DeviceID,
    Location.*
FROM input

O resultado é:

ID do dispositivo Lat Longo
12345 47 122

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

Use a função GetRecordPropertyValue se o nome da propriedade for uma variável. Ele permite a criação de consultas dinâmicas sem codificar nomes de propriedade.

Por exemplo, imagine que o fluxo de dados de amostra precisa ser unido com dados de referência contendo limites para cada sensor de dispositivo. Um trecho desses dados de referência é mostrado no trecho a seguir.

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

O objetivo aqui é unir nosso conjunto de dados de amostra da parte superior do artigo a esses dados de referência e gerar um evento para cada medida de sensor acima de seu limite. Isso significa que nosso único evento acima pode gerar vários eventos de saída se vários sensores estiverem acima de seus respetivos limites, graças à junção. Para obter resultados semelhantes sem uma associação, consulte o seguinte exemplo:

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, cujo nome corresponde ao nome da propriedade proveniente dos dados de referência. Em seguida, o valor associado de SensorReadings é extraído.

O resultado é:

ID do dispositivo SensorName AlertMessage
12345 Humidade Alerta: Sensor acima do limite

Converter campos de registro em eventos separados

Para converter campos de registro em eventos separados, use o operador APPLY junto com a função GetRecordProperties.

Com os dados de exemplo originais, a consulta a seguir pode ser usada para extrair propriedades em eventos diferentes.

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

O resultado é:

ID do dispositivo SensorName AlertMessage
12345 Temperatura 80
12345 Humidade 70
12345 CustomSensor01 5
12345 CustomSensor02 99
12345 SensorMetadata [objeto objeto]

Usando WITH, é possível rotear 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 registro JSON em dados de referência SQL

Ao usar o Banco de Dados SQL do Azure como dados de referência em seu trabalho, é possível ter uma coluna que tenha dados no formato JSON. Um exemplo é mostrado no exemplo a seguir:

ID do dispositivo Dados
12345 {"chave": "value1"}
54321 {"chave": "value2"}

Você pode analisar o registro JSON na coluna Dados escrevendo uma função JavaScript simples definida pelo usuário.

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

Em seguida, você pode criar uma etapa em sua consulta do Stream Analytics, conforme mostrado aqui, para acessar os campos de seus registros 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 aqui. Esses exemplos usam as funções GetArrayElement, GetArrayElements, GetArrayLength e o operador APPLY .

Aqui está um exemplo de um evento. Ambos CustomSensor03 e SensorMetadata são do tipo matriz:

{
    "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"
        }
    ]
}

Trabalhando com um elemento de matriz específico

Selecione o elemento da matriz em um índice especificado (selecionando o primeiro elemento da 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 é:

arrayLength
3

Converter elementos de matriz em eventos separados

Selecione todos os elementos da matriz como eventos individuais. O operador APPLY juntamente com a função interna GetArrayElements extrai todos os elementos da matriz como eventos individuais:

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

O resultado é:

DeviceId ArrayIndex 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 smValor
12345 Fabricante ABC
12345 Versão 1.2.45

Se os campos extraídos precisarem aparecer em colunas, é possível girar o conjunto de dados usando a sintaxe WITH , além da operação JOIN . Essa junçã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 smVersão smFabricante
12345 47 122 1.2.45 ABC

Tipos de dados no Azure Stream Analytics