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 |