Joins

Die Beispiele in diesem Thema zeigen, wie Werte aus unterschiedlichen Datenströmen mit einer Joinoperation korreliert werden. Eine Joinoperation vergleicht jedes Ereignis eines Eingabedatenstroms mit jedem Ereignis eines oder mehrerer anderer Eingabedatenströme des Typs CepStream. Wenn sich ihre Gültigkeitsintervalle überschneiden und die Joinbedingung erfüllt ist, erzeugt sie ein Ausgabeereignis.

Wie in LINQ üblich kann die Joinbedingung als Gleichheitsjoinprädikat zwischen zwei Eingabedatenströmen angegeben werden. Dies kann über eine on … equals-Klausel oder über eine where-Klausel erfolgen, die auf zwei oder mehr Eingabedatenströme verweisen kann. Das Gleichheitsjoinprädikat kann einzelne Felder vergleichen, wie z. B. in where x.a equals y.a, oder zusammengesetzte Schlüssel, z. B. mit where {x.a, x.b} equals {y.a, y.b} oder where x equals y.

Beispiele

Inner Join

Eine Inner Join-Operation gibt alle Ereignisse zweier oder mehrerer Eingabedatenströme zurück, wenn das Joinprädikat zwischen ihnen zu true ausgewertet wird. Ein Joinprädikat ist ein Ausdruck, der die Nutzlastfelder der Ereignisdatenströme vergleicht, die miteinander verknüpft werden. Ein Inner Join schließt alle Ereignisse aus, die nicht über ein übereinstimmendes Ereignis in den anderen angegebenen Ereignisdatenströmen verfügen.

Equi-Join

Im folgenden Beispiel werden Ereignisse im Datenstrom stream1 mit Ereignissen im Datenstrom stream2 verglichen. Ereignisse im Datenstrom, die die Gleichheitskriterien erfüllen, die in der Klausel on definiert wurden (zusätzlich zu sich überschneidenden Zeitintervallen der beiden Ereignisse), werden verknüpft und als ein neues Ereignis ausgegeben, das die Nutzlastfelder i und j von Ereignis e1 und Feld j von Ereignis e2 enthält.

// Assuming the following input event type for both stream1 and stream2.
public class MyPayload
{
    public int i;
    public float j;
}

var equiJoin = from e1 in stream1
               join e2 in stream2
               on e1.i equals e2.i
               select new { e1.i, e1.j, e2.j };

Das Gleichheitsprädikat ermöglicht den Vergleich von primitiven und zusammengesetzten Typen. Beispielsweise ist folgende Verknüpfung möglich: on {e1i, e1j} equals {e2i, e2j}.

Cross Join

Eine Cross Join-Operation (kartesisches Produkt) ergibt einen Ereignisdatenstrom, der die Kombination jedes Ereignisses vom ersten Datenstrom mit jedem Ereignis vom zweiten Datenstrom darstellt (für die Dauer der Überschneidung der Intervalle des Ereignisses aus jedem Datenstrom). Ein Filterausdruck kann in der Klausel where verwendet werden, um die Ereignisse von jedem Eingabedatenstrom zu begrenzen. Beachten Sie, dass ein Cross Join zweier Eingabedatenströme mit einer where-Klausel, der auf Gleichheit prüft, äquivalent ist zu einem Gleichheitsjoin mit einer entsprechenden on … equals-Klausel. Bei Prädikaten, die nicht auf Gleichheit prüfen, oder bei mehr als zwei Eingabedatenströmen muss ein Cross Join verwendet werden.

Im folgenden Beispiel werden Ereignisse in stream1, die über einen Wert im Nutzlastfeld i verfügen, der größer als 3 ist, mit Ereignissen aus stream2 mit einem Wert im Nutzlastfeld j, der kleiner als 10 ist, verknüpft.

var crossJoin = from e1 in stream1
                from e2 in stream2
                where e1.i > 3 && e2.j < 10
                select new { e1.i, e2.j };

Left Anti Semi Join

Die linke Antisemiverknüpfung (Left Anti Semi Join) führt nur zu einem Joinergebnis für jedes Ereignis auf der linken Seite, wenn das Ergebnis des normalen Joins für jeden Zeitpunkt leer ist. Dieser Vorgang ist nützlich, um Lücken mit 0 Ereignissen zu erkennen.

var leftAntiSemiJoin = from left in stream1 
                       where (from right in stream2 
                              where left.v == right.v
                              select right).IsEmpty()
                       select left;

Die folgende Abbildung zeigt das Joinergebnis von oben mit zwei Beispieleingabedatenströmen an. Hierbei wird davon ausgegangen, dass die Joinbedingung zu true ausgewertet wird. Außerdem wird das Zwischenergebnis für den normalen Join angezeigt.

Beispiel für einen Antisemijoin mit zwei Datenströmen

Verknüpfen mehrerer Datenströme

Sie können mehrere Datenströme in einer einzelnen Abfrage verknüpfen, wie im folgenden Beispiel gezeigt wird.

var slopetest = from f in fastSignal
                          from s in slowSignal
                          from r in refSignal
                          select new { alarm = f.avg / s.avg < r.Threshold };