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.
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 };