聯結

 

本主題中的範例將示範如何使用聯結作業,讓不同資料流中的值相互關聯。 聯結作業會將某個輸入資料流中的每一個事件與一個或多個其他輸入資料流中的每一個事件做比較。 如果其有效的時間間隔重疊而且聯結條件成立,則此作業會產生一個輸出事件。

如同往常在 LINQ 中,您可以在兩個輸入資料流之間,使用 on … equals 子句或透過可以參考兩個或多個輸入資料流的 where 子句,將聯結條件指定為等聯結 (Equi-Join) 述詞。 等聯結述詞可以比較 where x.a equals y.a 或複合索引鍵之類的單一欄位,例如 where {x.a, x.b} equals {y.a, y.b}where x equals y

範例

內部聯結

內部聯結作業會傳回兩個或多個輸入資料流中的所有事件,前提是兩者之間的聯結述詞評估為 true。 聯結述詞是一種運算式,可比較所聯結之事件資料流的裝載欄位。 內部聯結會排除在其他指定之事件資料流中沒有相符事件的所有事件。

等聯結

下列範例會比較 stream1 資料流中的事件與 stream2 資料流中的事件。 資料流中符合 on 子句所定義之相等準則的事件 (也會在兩個事件的時間間隔內重疊) 會聯結並輸出至新的事件,而這個新事件包含 e1 事件中的 ij 裝載欄位以及 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}

交叉聯結

交叉聯結 (笛卡兒乘積) 作業會傳回一個事件資料流,其中會在每一個資料流之事件間隔的重疊期間,結合第一個資料流中的每個事件與第二個資料流中的每個事件。 您可以在 where 子句中使用篩選運算式,以便限制每個輸入資料流中的事件。 請務必注意,對於兩個輸入資料流而言,包含可檢查是否相等之 where 子句的交叉聯結相當於包含對應 on … equals 子句的等聯結。 對於非相等述詞或兩個以上的輸入資料流,則必須使用交叉聯結。

在下列範例中,stream1i 裝載欄位之值大於 3 的事件會與 stream2j 裝載欄位之值小於 10 的事件聯結。

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


SelectMany 是方便使用的交叉聯結語法表示。 對於不參考資料流選取器參數的查詢,為 IQStreamable<> 撰寫的程式碼和為 CepStream<> 撰寫的程式碼之間沒有任何差異。

左方反半聯結

左方反半聯結只有在正常聯結的結果為空白時,才會針對每一個時間點於左邊產生每一個事件的聯結結果。 這個作業對於偵測零事件之間的間距很有幫助。

下列範例執行左方反半聯結。

left.LeftAntiJoin
(right, (x, y) => left.A > right.B)  
  

下圖顯示上述聯結結果且包含兩個範例輸入資料流,其中假設聯結條件評估為 true。 同時也會顯示中繼的一般聯結結果。

包括兩個串流的 Anti semi join 範例

System_CAPS_ICON_note.jpg 注意事項


在 StreamInsight 2.0 (含) 以前版本中,您必須針對 CepStream 資料流明確指定左方反半聯結,如下列範例所示。

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

聯結多個資料流

您可以在單一查詢中聯結多個資料流,如下列範例所示。

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