Benutzerdefinierte JavaScript-Funktionen in Azure Stream Analytics

Azure Stream Analytics unterstützt benutzerdefinierte Funktionen, die in JavaScript geschrieben sind. Durch die Verwendung der umfangreichen String-, RegExp-, Math-, Array- und Date-Methoden , die JavaScript bereitstellt, können Sie komplexe Datentransformationen in Stream Analytics-Jobs erstellen. Benutzerdefinierte JavaScript-Funktionen unterstützen zustandslose, skalare Funktionen für reine Berechnungen, die keine externe Konnektivität erfordern. Der Rückgabewert einer Funktion kann nur ein skalarer (einzelner) Wert sein. Nachdem Sie einem Auftrag eine benutzerdefinierte JavaScript-Funktion hinzugefügt haben, können Sie die Funktion wie eine integrierte Skalarfunktion an einer beliebigen Stelle in der Abfrage verwenden.

Dieser Artikel beschreibt, wann man benutzerdefinierte JavaScript-Funktionen verwenden sollte und wie man sie in Ihren Stream-Analytics-Jobs definiert und aufrufen kann.

Wann sollte man eine benutzerdefinierte JavaScript-Funktion verwenden

Hier finden Sie einige Szenarien, in denen benutzerdefinierte JavaScript-Funktionen hilfreich sein könnten:

  • Analysieren und Bearbeiten von Zeichenfolgen mit regulären Ausdrucksfunktionen, zum Beispiel Regexp_Replace() und Regexp_Extract()
  • Decodieren und Codieren von Daten, z.B. Konvertierung von binär in hexadezimal
  • Mathematische Berechnungen mit JavaScript-Mathematikfunktionen durchführen
  • Durchführen von Arrayvorgängen, z. B. Sortieren, Verknüpfen, Suchen und Füllen

Hier sind einige Dinge, die Sie mit einer benutzerdefinierten JavaScript-Funktion in Stream Analytics nicht machen können:

  • Externe REST-Endpunkte aufrufen, zum Beispiel durch eine umgekehrte IP-Abfrage oder das Abrufen von Referenzdaten aus einer externen Quelle
  • Führen Sie eine Serialisierung oder Deserialisierung benutzerdefinierter Ereignisformate für Ein- oder Ausgänge durch
  • Benutzerdefinierte Aggregate erstellen

Obwohl Funktionen wie Date.GetDate() oder Math.random() in der Funktionsdefinition nicht blockiert sind, sollten Sie sie vermeiden. Bei diesen Funktionen wird nicht bei jedem Aufruf das gleiche Ergebnis zurückgegeben, und im Azure Stream Analytics-Dienst wird kein Journal mit den Funktionsaufrufen und den zurückgegebenen Ergebnissen geführt. Wenn eine Funktion bei denselben Ereignissen ein anderes Ergebnis zurückgibt, ist die Wiederholbarkeit nicht garantiert, wenn du oder der Stream Analytics Service den Job neu starten.

Definieren einer benutzerdefinierten JavaScript-Funktion im Azure-Portal

Für einen Stream-Analytics-Job, der in der Cloud läuft, fügen Sie eine benutzerdefinierte JavaScript-Funktion auf der Funktionen-Seite unter Jobtopologie hinzu, wobei das +Add-Menü eine JavaScript-UDF-Option enthält.

Hinweis

Diese Erfahrung gilt auch für Stream-Analytics-Jobs, die für die Ausführung in der Cloud konfiguriert sind. Wenn Ihr Stream Analytics-Auftrag für die Ausführung in Azure IoT Edge konfiguriert ist, verwenden Sie stattdessen Visual Studio, und schreiben Sie die benutzerdefinierte Funktion mit C#.

Screenshot der Seite zu den Funktionen des Azure Portals, der das Menü hinzufügen mit der JavaScript-UDF-Option zeigt.

Eine Funktionsdefinition besteht aus folgenden Eigenschaften:

Eigenschaft BESCHREIBUNG
Funktionsalias Der Name, der die Funktion in deiner Abfrage aufruft.
Ausgabetyp Der Typ, den die benutzerdefinierte JavaScript-Funktion an Ihre Stream Analytics-Abfrage zurückgibt.
Funktionsdefinition Die Implementierung deiner JavaScript-Funktion, die jedes Mal ausgeführt wird, wenn das UDF aus deiner Abfrage aufgerufen wird.

Testen und fehlerbeheben Sie JavaScript-UDF-Logik

Da das Stream Analytics Portal das Debuggen und Testen der Logik dieser benutzerdefinierten Funktionen nicht unterstützt, können Sie Ihre JavaScript-UDF-Logik in jedem Browser testen und debuggen. Wenn die Funktion wie erwartet arbeitet, kann sie dem Stream Analytics-Job hinzugefügt und direkt in Ihrer Abfrage aufgerufen werden. Sie können Ihre Abfragelogik auch mit einem JavaScript-UDF testen, indem Sie die Stream Analytics Tools für Visual Studio verwenden.

Stream Analytics behandelt JavaScript-Laufzeitfehler als fatal und zeigt sie im Activity-Log. Das Protokoll ist im Azure-Portal auf der Seite Aktivitätsprotokoll Ihres Auftrags verfügbar.

Aufrufen benutzerdefinierter JavaScript-Funktionen in einer Abfrage

Um Ihre JavaScript-Funktion in Ihrer Abfrage zu aktivieren, verwenden Sie das Funktionsalias mit dem Präfix udf. Das folgende Beispiel zeigt ein JavaScript-UDF, das hexadezimale Werte in eine ganze Zahl in einer Stream Analytics-Abfrage umwandelt.

    SELECT
        time,
        UDF.hex2Int(offset) AS IntOffset
    INTO
        output
    FROM
        InputStream

Unterstützte JavaScript-Objekte

Azure Stream Analytics JavaScript-benutzerdefinierte Funktionen unterstützen die standardisierten, integrierten JavaScript-Objekte. Diese Objekte geben deinen Funktionen Zugriff auf gemeinsame String-, Mathematik-, Array- und Datumsoperationen ohne zusätzliche Konfiguration. Für eine vollständige Liste der verfügbaren Objekte siehe Globale Objekte. Da die Stream Analytics-Abfragesprache und JavaScript nicht dasselbe Typsystem teilen, wandelt Stream Analytics Werte um, während sie zwischen den beiden wechseln.

Stream Analytics und JavaScript-Typkonvertierung

Die Abfragesprache Stream Analytics und JavaScript unterstützen verschiedene Typen. Diese Tabelle listet die Konvertierungszuordnungen zwischen den beiden auf:

Stream Analytics JavaScript
BIGINT Number (in JavaScript können nur ganze Zahlen bis genau 2^53 dargestellt werden)
Datum/Uhrzeit Date (JavaScript unterstützt nur Millisekunden)
double Nummer
nvarchar(Max) String
Datensatz Objekt
Array Array
NULL Null

Konvertierungen von JavaScript zu Stream Analytics:

JavaScript Stream Analytics
Zahl bigint (wenn die Zahl gerundet ist und zwischen long.MinValue und long.MaxValue liegt, andernfalls double)
Datum Datum/Uhrzeit
String nvarchar(Max)
Objekt Datensatz
Array Array
Null, undefiniert NULL
Jeder andere Typ (zum Beispiel eine Funktion oder einen Fehler) Nicht unterstützt (führt zu einem Laufzeitfehler)

JavaScript ist groß- und kleinschreibungssensitiv, und das Gehäuse der Objektfelder im JavaScript-Code muss mit dem Gehäuse der Felder in den eingehenden Daten übereinstimmen. Jobs mit Kompatibilitätsstufe 1.0 wandeln Felder aus der SQL-SELECT-Anweisung in Kleinbuchstaben um. Ab Kompatibilitätsstufe 1.1 und höher haben Felder aus der SELECT-Anweisung das gleiche Gehäuse wie in der SQL-Abfrage angegeben.

Häufige Funktionsmuster

Die folgenden Muster zeigen gängige Methoden, um JavaScript-benutzerdefinierte Funktionen zu verwenden, um Daten in Ihren Stream Analytics-Abfragen zu transformieren. Jedes Muster enthält eine Funktionsdefinition und eine Beispielanfrage, die es aufruft.

Geschachteltes JSON in die Ausgabe schreiben

Wenn ein nachfolgender Verarbeitungsschritt die Ausgabe des Stream Analytics-Auftrags als Eingabe verwendet und das JSON-Format benötigt, können Sie eine JSON-Zeichenfolge in die Ausgabe schreiben. Die folgende Funktionsdefinition ruft die JSON.stringify()- Funktion auf, um alle Name/Wert-Paare der Eingabe zu packen und sie dann als einen einzelnen String-Wert in der Ausgabe zu schreiben.

function main(x) {
return JSON.stringify(x);
}

Eine Stream Analytics-Abfrage ruft die Funktion wie im folgenden Beispiel gezeigt auf.

SELECT
    DataString,
    DataValue,
    HexValue,
    UDF.jsonstringify(input) As InputEvent
INTO
    output
FROM
    input PARTITION BY PARTITIONID

Umwandeln einer Zeichenfolge in ein JSON-Objekt für die Verarbeitung

Wenn du ein String-Feld hast, das JSON ist, und es in ein JSON-Objekt für die Verarbeitung in einem JavaScript-UDF umwandeln möchtest, kannst du die Funktion JSON.parse() verwenden, um ein JSON-Objekt zu erstellen, das du dann verwenden kannst. Die folgende Funktionsdefinition parst die Zeichenkette und gibt eine Eigenschaft vom resultierenden Objekt zurück.

function main(x) {
var person = JSON.parse(x);  
return person.name;
}

Eine Stream Analytics-Abfrage ruft die Funktion wie im folgenden Beispiel gezeigt auf.

SELECT
    UDF.getName(input) AS Name
INTO
    output
FROM
    input

Verwenden von try/catch zur Fehlerbehandlung

Try/Catch-Blocks können dir helfen, Probleme mit fehlgeleiteten Eingabedaten zu identifizieren, die du in ein JavaScript-UDF übergibst. Die folgende Funktionsdefinition verwendet einen Try/Catch-Block zur Behandlung von Parsingfehlern.

function main(input, x) {
    var obj = null;

    try{
        obj = JSON.parse(x);
    }catch(error){
        throw input;
    }
    
    return obj.Value;
}

In der folgenden Beispielabfrage gibst du den gesamten Datensatz als ersten Parameter ein, damit die Funktion ihn bei einem Fehler zurückgeben kann.

SELECT
    A.context.company AS Company,
    udf.getValue(A, A.context.value) as Value
INTO
    output
FROM
    input A

toLocaleString()

Die toLocaleString-Methode in JavaScript liefert eine sprachsensitive Zeichenkette zurück, die die Datum-Zeit-Daten darstellt, von denen aus Sie die Methode aufrufen. Obwohl Azure Stream Analytics nur UTC-Datumszeit als Systemzeitstempel akzeptiert, können Sie diese Methode nutzen, um den Systemzeitstempel in einen anderen Standort und eine andere Zeitzone umzuwandeln. Diese Methode folgt demselben Implementierungsverhalten wie das im Internet Explorer verfügbare. Die folgende Funktionsdefinition wandelt die Eingabe-Datumszeit in den de-DE Standort um.

function main(datetime){
    const options = { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' };
    return datetime.toLocaleDateString('de-DE', options);
}

In der folgenden Beispielabfrage wird als Eingabewert ein Datumszeitpunkt angegeben.

SELECT
    udf.toLocaleString(input.datetime) as localeString
INTO
    output
FROM
    input

Die Ausgabe dieser Abfrage ist die Eingabe-Datumszeit in de-DE mit den bereitgestellten Optionen.

Samstag, 28. December 2019

Benutzerprotokollierung

Logging ist der Mechanismus, den Azure Stream Analytics verwendet, um benutzerdefinierte Informationen aus einer benutzerdefinierten JavaScript-Funktion zu erfassen, während ein Job ausgeführt wird. Da ein laufender Job ansonsten undurchsichtig ist, verschaffen dir Logdaten in Echtzeit Einblick in das Verhalten und die Korrektheit deines benutzerdefinierten Codes. Jede Log-Nachricht trägt eine Ereignisebene, die angibt, wie bedeutend die Nachricht ist und ob der Job weiterlaufen kann.

Informationsbotschaften stammen aus der console.info()- Methode, wie zum Beispiel console.info('my info message');. Dieses Level erfasst während der Ausführung allgemeine Informationen und unterbricht die Berechnung nicht. Warnmeldungen stammen von der Methode console.warn(), wie zum Beispiel console.warn('my warning message');. Dieses Level speichert Daten, die unerwartet sein könnten, aber dennoch für die Berechnung geeignet sind, sodass der Job weiterläuft. Fehlermeldungen stammen von den Methoden console.error() und console.log(), wie zum Beispiel console.error('my error message');. Diese Methoden gelten nur für Fälle, in denen der Code nicht fortgesetzt werden kann, daher wird eine Ausnahme mit den angegebenen Fehlerinformationen geworfen und der Job gestoppt.

Sie können über die Diagnoseprotokolle auf Protokollmeldungen zugreifen.

„atob()“ und „btoa()“

Stream Analytics unterstützt zwei Methoden zur Base64-Konvertierung, einer gängigen Methode, binäre Daten als Text zu kodieren. Die btoa() -Methode kodiert eine ASCII-Zeichenkette in Base64, und die atob()- Methode dekodiert eine Zeichenkette von Base64-kodierten Daten zurück in eine ASCII-Zeichenkette. Im folgenden Beispiel btoa() kodiert man eine ASCII-Zeichenkette und atob() dekodiert das Ergebnis dann zurück in die ursprüngliche Zeichenkette.

var myAsciiString = 'ascii string';
var encodedString = btoa(myAsciiString);
var decodedString = atob(encodedString);