Azure流分析查询来检测特定deviceId的缺少的活动事件

时间:2018-11-21 16:30:24

标签: azure tsql azure-stream-analytics

我没有看到一种使用天蓝色流分析查询语言来分析缺少特定事件的流的方法。 流可能包含DeviceAlive和BeaconDetected事件,其中包含DeviceId,在BeaconDetected的情况下,还包含BeaconId。现在,如果缺少DeviceAlive事件,我想生成一个错误事件。

我该如何实现? 我尝试将参考数据与所有有效的deviceId一起使用。 但是我不允许这样进行linq明智的“包含”查询

SELECT * FROM
     inputStream
WHERE DeviceId IN (SELECT Id FROM DeviceReferenceData)

如何进行此类查询。通过将inputStream与DeviceReferenceData表连接起来是否可能? 我想我只是看不到明显的东西。

事件,例如看起来像这样:

 {
    "EventType": "DeviceAlive",
    "DeviceId": "winiot-pi",
    "EventEnqueuedUtcTime": "2018-11-19T11:00:20.5594584+01:00"
 },
 {
    "EventType": "BeaconDetected",
    "BeaconId": "2",
    "DeviceId": "winiot-pi",
    "EventEnqueuedUtcTime": "2018-11-19T11:00:20.5594584+01:00"
 }

进行这样的查询不会产生预期的结果:

SELECT
    iothub.*,r.id as rerId
into output
FROM
    iothub TIMESTAMP BY EventEnqueuedUtcTime
Left OUTER Join devicesReference r on iothub.DeviceId = r.Id

这只会为每个DeviceAlive事件返回一个NULL referenceId。 csv中的输出:

eventenqueuedutctime;EventType;BeaconId;DeviceId;SignalStrength;rerid
19.11.2018 10:00:20;BeaconDetected;1;winiot-pi;-40;winiot-pi
19.11.2018 10:00:20;BeaconDetected;1;winiot-pi2;-80;winiot-pi2
19.11.2018 10:00:20;ReceiverDeviceAlive;winiot-pi;winiot-pi;;
19.11.2018 10:00:21;ReceiverDeviceAlive;winiot-pi2;winiot-pi2;;
19.11.2018 10:00:21;BeaconDetected;2;winiot-pi;-80;winiot-pi
19.11.2018 10:00:21;BeaconDetected;2;winiot-pi2;-40;winiot-pi2
19.11.2018 10:00:25;ReceiverDeviceAlive;winiot-pi;winiot-pi;;
19.11.2018 10:00:25;ReceiverDeviceAlive;winiot-pi2;winiot-pi2;;
19.11.2018 10:00:31;BeaconDetected;1;winiot-pi2;-40;winiot-pi2
19.11.2018 10:00:31;BeaconDetected;1;winiot-pi;-80;winiot-pi
19.11.2018 10:00:32;BeaconDetected;2;winiot-pi;-40;winiot-pi
19.11.2018 10:00:32;BeaconDetected;2;winiot-pi;-40;winiot-pi
19.11.2018 10:00:33;BeaconDetected;2;winiot-pi2;-80;winiot-pi2
19.11.2018 10:00:36;BeaconDetected;2;winiot-pi;-40;winiot-pi
19.11.2018 10:00:46;BeaconDetected;2;winiot-pi2;-80;winiot-pi2
19.11.2018 10:00:46;BeaconDetected;2;winiot-pi;-40;winiot-pi
19.11.2018 10:00:57;BeaconDetected;2;winiot-pi2;-80;winiot-pi2
19.11.2018 10:00:57;BeaconDetected;2;winiot-pi;-40;winiot-pi
19.11.2018 10:01:07;BeaconDetected;2;winiot-pi2;-80;winiot-pi2
19.11.2018 10:01:07;BeaconDetected;2;winiot-pi;-40;winiot-pi
19.11.2018 10:01:20;ReceiverDeviceAlive;winiot-pi2;winiot-pi2;;
19.11.2018 10:01:30;ReceiverDeviceAlive;winiot-pi2;winiot-pi2;;

但是,如果该窗口不包含任何事件,那么我需要的是每个时间窗口上的信息。我们可以将其分解为我猜的那个问题: 如何查询和查看没有所需事件的时间窗口。 完全有可能吗?

谢谢您的帮助。

2 个答案:

答案 0 :(得分:2)

与同事交谈是一个很好的建议,即使他不完全了解您在说什么。 ;-) 这是用于通过参考设备表在专用设备的30秒窗口中检测到未激活事件来生成错误事件的解决方案。 这些链接使我对它有了更多的了解:

azure stream analytics query to detect missing alive event for a specific device

how to find absence of signal in a stream analytics job

WITH OneEvent AS /* generate one event per period, any event */
(
            SELECT 
                COUNT(*) As eventCount,
                System.Timestamp as EndOfWindow
            FROM iothub TIMESTAMP BY EventEnqueuedUtcTime
            GROUP BY TumblingWindow(s, 30)
),
AllReferenceDevices AS /* generate one event per deviceId per period */
(
            SELECT devicesReference.Id, OneEvent.EndOfWindow
            FROM OneEvent JOIN devicesReference
            ON OneEvent.EndOfWindow = OneEvent.EndOfWindow
),
/* Select only the devices where we cannot find an event for */
DeviceConnectivityErrorDetection AS
(
    SELECT 
        'DeviceConnectivityErrorDetected' AS EventType,
        AllReferenceDevices.Id as FromDeviceId,
        AllReferenceDevices.Id as ToDeviceId,
        AllReferenceDevices.EndOfWindow as EventEnqueuedUtcTime
    FROM 
        AllReferenceDevices 
      LEFT join  iothub  TIMESTAMP BY EventEnqueuedUtcTime
   ON DATEDIFF(s, iothub, AllReferenceDevices ) BETWEEN 0 and 30 
            AND iothub.DeviceId = AllReferenceDevices.Id
    WHERE iothub IS NULL
 ) 


SELECT  *
INTO ReceiverDeviceConnectivityErrorDetectedOutput
FROM DeviceConnectivityErrorDetection

答案 1 :(得分:1)

根据您的要求,也许您可​​以使用JOIN reference Data查找参考数据集合中缺少的deviceId。请尝试以下sql:

SELECT
    jsoninput.*,r.id as rerId
into output
FROM
    jsoninput
Left OUTER Join jsonreference r on jsoninput.id = r.id
where r.id is null