Share via


結合

このトピックの例では、結合演算を使用して、異なるストリームの値を相互に関連付ける方法を示します。結合演算では、1 つの入力ストリームの各イベントを CepStream の種類の 1 つまたは複数の入力ストリームの各イベントと比較します。両者の有効な期間が重複しており、結合条件が有効である場合は、1 つの出力イベントが生成されます。

通常どおり LINQ では、複数の入力ストリームを参照できる on … equals 句または where 句により、結合条件を 2 つの入力ストリーム間の等結合述語として指定できます。等結合述語は、where x.a equals y.a のように単一フィールドを比較することも、where {x.a, x.b} equals {y.a, y.b} または where x equals y のように複合キーを比較することもできます。

使用例

Inner Join

内部結合演算では、複数の入力ストリーム間の結合述語が true として評価される場合に、2 つ以上の入力ストリームからすべてのイベントを返します。結合述語は、結合されているイベント ストリームのペイロード フィールドを比較する式です。内部結合では、指定された他方のイベント ストリーム内に一致するイベントがないすべてのイベントが除外されます。

Equi Join

次の例では、ストリーム stream1 のイベントをストリーム stream2 のイベントと比較します。on 句で定義された等価条件に一致する、ストリーム内のイベント (2 つのイベントの期間は重複しています) が結合され、新しいイベントに出力されます。このイベントには、イベント e1 のペイロード フィールド i および j と、イベント e2 のフィールド j が含まれています。

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

等値述語では、プリミティブ型と複合型を比較できます。たとえば on {e1i, e1j} equals {e2i, e2j} を結合することができます。

Cross Join

クロス結合 (デカルト積) 演算では、各ストリームのイベントの間隔が重複している間、1 つ目のストリームの各イベントと 2 つ目のストリームの各イベントを組み合わせた 1 つのイベント ストリームを返します。各入力ストリームからのイベントを制限するために、where 句内でフィルター式を使用できます。2 つの入力ストリームでは、等しいかどうかをチェックする where 句のあるクロス結合は、対応する on … equals 句のある等結合と同等です。不等値述語または複数の入力ストリームにはクロス結合を使用する必要があります。

次の例では、ペイロード フィールド i の値が 3 よりも大きい stream1 のイベントが、ペイロード フィールド j の値が 10 未満の stream2 のイベントと結合されます。

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

Left Anti-Semi-Join は、各時点における通常の結合の結果が空の場合に、左側の各イベントの結合結果を作成します。この演算は、イベントがないギャップを検出する際に便利です。

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

次の図は、結合条件が True と評価されていることを前提に、2 つの入力ストリーム例を使用した上記の結合結果を示します。中間の通常結合の結果も表示されています。

2 つのストリームの Anti Semi Join の例。

複数のストリームの結合

次の例のように、1 つのクエリで複数のストリームを結合できます。

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