Flink學習筆記之TableAPI

Flink中Table API & SQL簡單介紹

對於像DataFrame這樣的關係型編程接口,因其強大且靈活的表達能力,能夠讓用戶通過非常豐富的接口對數據進行處理,有效降低了用戶的使用成本,近年來逐漸成爲主流大數據處理框架主要接口形式之一。Flink也提供了關係型編程接口Table API以及基於TableAPISQL API,讓用戶能夠通過使用結構化編程接口高效的構建Flink應用。同時Table API以及SQL能夠統一處理批量和實時計算業務,無需切換到修改任何應用代碼就能夠基於同一套API編寫流式應用和批量應用,從而達到真正意義的批流統一。

Apache Flink具有兩個關係API - 表APISQL- 用於統一流和批處理。Table APIScalaJava的語言集成查詢API,允許以非常直觀的方式組合來自關係運算符的查詢,Table APISQL接口彼此緊密集成,以及FlinkDataStreamDataSet API。您可以輕鬆地在基於API構建的所有API和庫之間切換。例如,您可以使用CEP庫從DataStream中提取模式,然後使用Table API分析模式,或者可以在預處理上運行Gelly圖算法之前使用SQL查詢掃描,過濾和聚合批處理表數據。

兩個規劃者之間的主要差異

  1. Blink將批處理作業視爲流式傳輸的特例。因此,也不支持Table和DataSet之間的轉換,批處理作業不會轉換爲Dataset程序,而是轉化爲DataStream程序,與流作業相同。
  2. Blink planner不支持BatchTableSource,使用有界StreamTableSource而不是它。
  3. Blink規劃器僅支持全新Catalog,不支持ExternalCatalog已棄用。
  4. 舊計劃程序和Blink計劃程序的FilterableTableSource的實現是不兼容的。 舊計劃者將PlannerExpressions推向FilterableTableSource,而Blink計劃者將推下表達式。
  5. 基於字符串的鍵值配置選項(有關詳細信息,請參閱有關配置的文檔)僅用於Blink規劃器。
  6. PlannerConfig在兩個規劃者中的實現(CalciteConfig)是不同的。
  7. Blink規劃器將多個接收器優化爲一個DAG(僅在TableEnvironment上支持,而不在StreamTableEnvironment上支持)。 舊規劃器將始終將每個接收器優化爲新的DAG,其中所有DAG彼此獨立。
  8. 現在,舊規劃器不支持目錄統計,而Blink規劃器則支持。

TableEnvironmetnt認識

DataStream一樣,Table APISQL中具有相同的基本編程模型。首先需要構建對應的TableEnvironment創建關係型編程環境,才能夠在程序中使用Table APISQL來編寫程序,另外Table APISQL接口可以在應用中同時使用。Flink SQL基於Apache Cacite框架實現SQL協議,是構建在Table API之上的更高級接口。

表API和SQL程序的結構

// JAVA
TableEnvironment tableEnv = ...; // see "Create a TableEnvironment" section

// register a Table
tableEnv.registerTable("table1", ...)            // or
tableEnv.registerTableSource("table2", ...);     // or
tableEnv.registerExternalCatalog("extCat", ...);

// register an output Table
tableEnv.registerTableSink("outputTable", ...);

// create a Table from a Table API query
Table tapiResult = tableEnv.scan("table1").select(...);
// create a Table from a SQL query
Table sqlResult  = tableEnv.sqlQuery("SELECT ... FROM table2 ... ");

// emit a Table API result Table to a TableSink, same for SQL result
tapiResult.insertInto("outputTable");
// execute
tableEnv.execute("java_job");

創建一個TableEnvironment

TableEnvironmentTable APISQL集成的核心概念,他主要負責:

  • Table內部目錄中註冊表
  • 註冊一個外部表
  • 執行SQL查詢
  • 註冊用戶行爲的(標量,表或聚合)函數
  • DataStream或者DataSet轉換爲Table
  • 持有對ExecutionEnvironment或的引用StreamExecutionEnvironment

表始終綁定到特定的TableEnvironment。 不可能在同一查詢中組合不同TableEnvironments的表,例如,加入或聯合它們。

通過使用StreamExecutionEnvironmentExecutionEnvironment和可選的TableConfig調用靜態BatchTableEnvironment.create()StreamTableEnvironment.create()方法來創建TableEnvironmentTableConfig可用於配置TableEnvironment或自定義查詢優化和轉換過程.

開發環境構建

<dependency>
            <groupId>org.apache.flink</groupId>
            <artifactId>flink-java</artifactId>
            <version>${flink.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.flink</groupId>
            <artifactId>flink-core</artifactId>
            <version>${flink.version}</version>
        </dependency>

        <dependency>
            <groupId>org.apache.flink</groupId>
            <artifactId>flink-streaming-java_${scala.binary.version}</artifactId>
            <version>${flink.version}</version>
        </dependency>
        <!--Flink Table API / sql-->
        <dependency>
            <groupId>org.apache.flink</groupId>
            <artifactId>flink-table-api-java-bridge_${scala.binary.version}</artifactId>
            <version>${flink.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.flink</groupId>
            <artifactId>flink-table-planner_${scala.binary.version}</artifactId>
            <version>${flink.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.flink</groupId>
            <artifactId>flink-table-common</artifactId>
            <version>${flink.version}</version>
        </dependency>

Note 1 : 由於Flink Table接口中引入了Apache Calcite第三方庫,會阻止Java虛擬機對用戶的Classloaders進行垃圾回收,因此不建議用戶在構建Flink應用時將flink table依賴包打包進fat-jar中,可以在集羣環境中將{FLINK_HOME}/opt的對應的flink-table jar複製到{FLINK_HOME}/lib中解決此類問題。

Note 2 : If there is only one planner jar in /lib directory, you can use useAnyPlanner (use_any_planner for python) to create specific EnvironmentSettings.

TableEnvironment基本操作

使用Table API & SQL創建Flink應用程序,需要在環境中創建TableEnvironment對象,TableEnvironment提供了註冊內部表,執行Flink SQL語句、註冊自定義函數等功能。

// 批處理環境
ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
// 獲取表操作環境對象
BatchTableEnvironment tableEnvironment = BatchTableEnvironment.create(env);

// 流處理環境
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
// 獲取表操作環境對象
StreamTableEnvironment tableEnvironment = StreamTableEnvironment.create(env);

內部CataLog註冊

內部Table註冊

在獲取TableEnvironment對象後,可以使用TableEnvironment提供的方法來註冊相應的數據源和數據表信息。所有對數據庫和數據表的元數據信息存放在Flink CataLog內部目錄中,其存放了Flink內部所有與Table相關的元數據信息,包括表的結構信息,數據源信息等。

Table nameSumDeptid = tableEnvironment.scan("emp").select("name,deptid,email");
// 將 nameSumDeptid 在CataLog中註冊成內部表 nameTable
tableEnvironment.registerTable("nameTable" , nameSumDeptid)

TableSource註冊

在使用Table API,可以將外部數據源直接註冊成Table數據結構。

// 批處理環境
ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
// 獲取表操作環境對象
BatchTableEnvironment tableEnvironment = BatchTableEnvironment.create(env);
// 創建csv文件類型的TableSource
TableSource csvSource = new CsvTable("/file.csv" , ",");
// 將創建好的TableSource註冊到BatchTableEnvironment
tableEnvironment.registerTableSource("CsvTable" , csvSource);

表API

掃描表Orders,並按照a字段進行分組聚合,查找ab的數量並將b的計數取名爲cnt

Table orders = tEnv.scan("Orders"); // schema (a, b, c, rowtime)
Table counts = orders
        .groupBy("a")
        .select("a, b.count as cnt");

// conversion to DataSet
DataSet<Row> result = tEnv.toDataSet(counts, Row.class);
result.print();

下一個示例顯示了一個更復雜的Table API程序。程序再次掃描Orders表格。它過濾空值,規範化aString類型的字段,並計算每小時和產品a的平均計費金額b

Table orders = tEnv.scan("Orders"); // schema (a, b, c, rowtime)

Table result = orders
        .filter("a.isNotNull && b.isNotNull && c.isNotNull")
        .select("a.lowerCase() as a, b, rowtime")
        .window(Tumble.over("1.hour").on("rowtime").as("hourlyWindow"))
        .groupBy("hourlyWindow, a")
        .select("a, hourlyWindow.end as hour, b.avg as avgBillingAmount");

Scan, Projection, and Filter

Operators Description
Scan
與SQL查詢中的FROM子句類似。 執行已註冊表的掃描.
Table orders = tableEnv.scan("Orders");
Select 與SQL SELECT語句類似。 執行選擇操作。
Table orders = tableEnv.scan("Orders");
Table result = orders.select("a, c as d");
You can use star (*) to act as a wild card, selecting all of the columns in the table.
Table result = orders.select("*");
As Renames fields.Table orders = tableEnv.scan("Orders"); Table result = orders.as("x, y, z, t");
Where / Filter 與SQL WHERE子句類似。 過濾掉未通過過濾謂詞的行.
Table orders = tableEnv.scan("Orders");
Table result = orders.where("b === 'red'");
Table orders = tableEnv.scan("Orders"); Table result = orders.filter("a % 2 === 0");

Column Operations

Operators Description
AddColumns 執行字段添加操作。 如果添加的字段已存在,它將拋出異常。
Table orders = tableEnv.scan("Orders");
Table result = orders.addColumns("concat(c, 'sunny')");
AddOrReplaceColumns 執行字段添加操作。 如果添加列名稱與現有列名稱相同,則將替換現有字段。 此外,如果添加的字段具有重複的字段名稱,則使用最後一個字段。
Table orders = tableEnv.scan("Orders");
Table result = orders.addOrReplaceColumns("concat(c, 'sunny') as desc");
DropColumns 執行字段放置操作。 字段表達式應該是字段引用表達式,並且只能刪除現有字段.
Table orders = tableEnv.scan("Orders"); Table result = orders.dropColumns("b, c");
RenameColumns 執行字段重命名操作。 字段表達式應該是別名表達式,並且只能重命名現有字段。
Table orders = tableEnv.scan("Orders");
Table result = orders.renameColumns("b as b2, c as c2");

Aggregations

Operators Description
GroupBy Aggregation 與SQL GROUP BY子句類似。使用以下運行的聚合運算符對分組鍵上的行進行分組,以按組聚合行。
Table orders = tableEnv.scan("Orders");
Table result = orders.groupBy(“a”).select(“a, b.sum as d”);`
Note: 對於流式查詢,計算查詢結果所需的狀態可能會無限增長,具體取決於聚合類型和不同分組鍵的數量。請提供具有有效保留間隔的查詢配置,以防止狀態過大
GroupBy Window Aggregation 組和聚合組窗口上的表以及可能的一個或多個分組鍵。
在這裏插入圖片描述
Over Window Aggregation Streaming 類似於SQL OVER子句。基於前一行和後一行的窗口(範圍)計算每行的窗口聚合在這裏插入圖片描述
Note: 必須在同一窗口中定義所有聚合,即相同的分區,排序和範圍。目前,僅支持具有PRREDING(UNBOUNDED和有界)到CURRENT ROW範圍的窗口。尚不支持使用FOLLOWING的範圍。必須在單個時間屬性上指定ORDER BY 。
Distinct Aggregation 類似於SQL DISTINCT聚合子句,例如COUNT(DISTINCT a)。不同聚合聲明聚合函數(內置或用戶定義)僅應用於不同的輸入值。Distinct可以應用於GroupBy聚合GroupBy窗口聚合Over Window Aggregation
在這裏插入圖片描述
Note: 用戶定義的聚合函數也可以與DISTINCT修飾符一起使用。要僅爲不同的值計算聚合結果,只需將distinct修飾符添加到聚合函數即可。
[外鏈圖片轉存失敗在這裏插入圖片描述
Note: 對於流式查詢,計算查詢結果所需的狀態可能會無限增長,具體取決於不同字段的數量。請提供具有有效保留間隔的查詢配置,以防止狀態過大。
Distinct 與SQL DISTINCT子句類似。返回具有不同值組合的記錄。
[外鏈圖片轉存失敗在這裏插入圖片描述
對於流式查詢,計算查詢結果所需的狀態可能會無限增長,具體取決於不同字段的數量。請提供具有有效保留間隔的查詢配置,以防止狀態過大。如果啓用了狀態清除,則distinct必須發出消息以防止下游運營商的過早狀態驅逐,這使得distinct包含結果更新.

Joins

Operators Description
Inner Join 與SQL JOIN子句類似。加入兩張桌子。兩個表必須具有不同的字段名稱,並且必須通過連接運算符或使用where或filter運算符定義至少一個相等連接謂詞。
在這裏插入圖片描述
**Note 😗*對於流式查詢,計算查詢結果所需的狀態可能會無限增長,具體取決於不同輸入行的數量。請提供具有有效保留間隔的查詢配置,以防止狀態過大
Outer Join 與SQL LEFT / RIGHT / FULL OUTER JOIN子句類似。加入兩張桌子。兩個表必須具有不同的字段名稱,並且必須至少定義一個相等連接謂詞。
在這裏插入圖片描述
Time-windowed Join 時間窗口連接是可以以流方式處理的常規連接的子集。
時間窗口連接需要至少一個等連接謂詞和一個限制雙方時間的連接條件。這樣的條件可以由兩個適當的範圍謂詞(<, <=, >=, >)或單個等式謂詞來定義,該單個等式謂詞比較兩個輸入表的相同類型的時間屬性(即,處理時間或事件時間)。
在這裏插入圖片描述
Inner Join with Table Function 使用表函數的結果連接表。 左(外)表的每一行與表函數的相應調用產生的所有行連接。 如果其表函數調用返回空結果,則刪除左(外)表的一行。
在這裏插入圖片描述
Left Outer Join with Table Function 使用表函數的結果連接表。 左(外)表的每一行與表函數的相應調用產生的所有行連接。 如果表函數調用返回空結果,則保留相應的外部行,並使用空值填充結果。
在這裏插入圖片描述
Join with Temporal Table 時態表是跟蹤隨時間變化的表。
時態表函數提供對特定時間點的時態表的狀態的訪問。 使用時態表函數連接表的語法與使用表函數的內部連接相同。
目前僅支持具有時態表的內部聯接。
在這裏插入圖片描述

Set Operations

Operators Description
Union 與SQL UNION子句類似。 聯合兩個表刪除了重複記錄。 兩個表必須具有相同的字段類型。
在這裏插入圖片描述
UnionAll 類似於SQL UNION ALL子句。 工會兩張桌子。 兩個表必須具有相同的字段類型。
在這裏插入圖片描述
Intersect 類似於SQL INTERSECT子句。 Intersect返回兩個表中存在的記錄。 如果一個或兩個表不止一次出現記錄,則只返回一次,即結果表沒有重複記錄。 兩個表必須具有相同的字段類型。
在這裏插入圖片描述
IntersectAll 類似於SQL INTERSECT ALL子句。 IntersectAll返回兩個表中存在的記錄。 如果兩個表中的記錄多次出現,則返回的次數與兩個表中的記錄一樣多,即結果表可能具有重複記錄。 兩個表必須具有相同的字段類型。
在這裏插入圖片描述
Minus 與SQL EXCEPT子句類似。 減號返回左表中右表中不存在的記錄。 左表中的重複記錄只返回一次,即刪除重複項。 兩個表必須具有相同的字段類型。
在這裏插入圖片描述
MinusAll 類似於SQL EXCEPT ALL子句。 MinusAll返回右表中不存在的記錄。 在左表中出現n次並在右表中出現m次的記錄返回(n-m)次,即,刪除右表中出現的重複數。 兩個表必須具有相同的字段類型。
在這裏插入圖片描述
In 與SQL IN子句類似。 如果表達式存在於給定的表子查詢中,則返回true。 子查詢表必須包含一列。 此列必須與表達式具有相同的數據類型。在這裏插入圖片描述

OrderBy, Offset & Fetch

Operators Description
Order By 與SQL ORDER BY子句類似。 返回跨所有並行分區全局排序的記錄。在這裏插入圖片描述
Offset & Fetch 類似於SQL OFFSET和FETCH子句。 偏移和提取限制從排序結果返回的記錄數。 Offset和Fetch在技術上是Order By運算符的一部分,因此必須以它爲前綴。在這裏插入圖片描述

Insert

Operators Description
Insert Into 類似於SQL查詢中的INSERT INTO子句。 執行插入已註冊的輸出表。在這裏插入圖片描述

Group Windows

Group WindowDataStream APIDataSet API中提供的窗口一致,都是將流式數據集根據窗口;類型切分爲有界數據集,然後在有界數據集上進行聚合類運算。

tableEnv.scan("Sensors")
    .winwods([w : Window] as "window") // 指定窗口類型,並命名爲window
    .groupBy("window") // 根據窗口進行聚合,窗口數據會分配到單個Task算子中
    .select("varl1.sum") // 指定對var字段進行Sum求和

在流式計算中,GroupBy聚合條件可以以上實例選擇Window名稱,也可以是一個或多個Key值與Window的組合。

  • 如果指定Window名稱,則和Global Window相似,窗口中的數據都會被彙總到一個Task線程中處理,統計窗口全局的結果;
  • 如果指定KeyWindow名稱組合,則窗口中的數據分佈到並行計算的算子實例中去計算結果。
tableEnv.scan("Sensors")
    .window([w:Window] as "window") // 
    .groupBy("window" , "id") // 根據窗口聚合,窗口數據分配到每單個Task算子
    .select("id" , "var1.sum") // 指定val字段求和

select語句中,我們除了可以獲取到數據元素以外,還可以獲取到窗口的元數據信息。

tableEnv.scan("Sensors")
    .window([w:Window] as "window") // 
    .groupBy("window" , "id") // 根據窗口聚合,窗口數據分配到每單個Task算子
    .select("id" , "var1.sum","window.start","window.end","window.rowtime") // 指定val字段求和

**Note : ** 在以上window()方法中需要指定的是不同的窗口類型,已確定數據元素被分配到窗口的邏輯。在Table API中支持Tumble , Sliding , Session Window三種窗口類型,並分別通過不同的Window對象來完成定義。

Tumbling Window(滾動窗口)

前面提到滾動窗口的窗口長度是固定的,窗口之間的數據不會重合。滾動窗口可以基於Evenet TimeProcess Time以及Row-Count來定義。如下實例:Table API中滾動窗口使用Tumble Class來創建,且分別基於Evenet TimeProcess Time以及Row-Count來定義窗口。

// 通過scan方法在CataLog中查詢Sensors表
tableEnv.scan("Sensors")
    // Tumbling Event-time Window
    .window(Tumble.over("10.minutes").on("rowtime").as("w"));
    // Tumbling Processing-time Window (assuming a processing-time attribute "proctime")
    .window(Tumble.over("10.minutes").on("proctime").as("w"));
    // Tumbling Row-count Window (assuming a processing-time attribute "proctime")
    .window(Tumble.over("10.rows").on("proctime").as("w"));
  • over : 指定窗口的長度
  • on : 定義了窗口基於的時間概念類型爲EventTime還是ProcessTimeEventTime對應着rowtimeProcessTime對應着proctime
  • as : 將創建的窗口重命名,同時窗口名稱需要在後續的孫子中使用。

Sliding Window(滑動窗口)

滑動窗口的長度也是固定的,但窗口與窗口之間的數據能夠重合。滑動窗口可以基於Evenet TimeProcess Time以及Row-Count來定義。如下實例:Table API中滑動窗口使用Slide Class來創建,且分別基於Evenet TimeProcess Time以及Row-Count來定義窗口。

// 通過scan方法在CataLog中查詢Sensors表
tableEnv.scan("Sensors")
    // Sliding Event-time Window
    .window(Slide.over("10.minutes").every("5.minutes").on("rowtime").as("w"));
    // Sliding Processing-time window (assuming a processing-time attribute "proctime")
    .window(Slide.over("10.minutes").every("5.minutes").on("proctime").as("w"));
    // Sliding Row-count window (assuming a processing-time attribute "proctime")
    .window(Slide.over("10.rows").every("5.rows").on("proctime").as("w"));
  • over : 定義窗口的長度,可以是時間或行計數間隔。
  • every : 定義滑動間隔,可以是時間間隔也可以是行數。滑動間隔必須與大小間隔的類型相同。
  • on : 定義了窗口基於的時間概念類型爲EventTime還是ProcessTimeEventTime對應着rowtimeProcessTime對應着proctime
  • as : 將創建的窗口重命名,同時窗口名稱需要在後續的孫子中使用。

Session Window(會話窗口)

TumblingSliding 窗口不同的是,Session窗口不需要指定固定的窗口時間,而是通過判斷固定時間內數據的活躍性來切分窗口。例如 10 min內數據不接入則切分窗口並觸發計算。Session窗口只能基於EventTimeProcessTime時間概念來定義,通過withGrap操作符指定數據不活躍的時間Grap,表示超過該時間數據不接入,則切分窗口並觸發計算。

// 通過scan方法在CataLog中查詢Sensors表
tableEnv.scan("Sensors")
    // Session Event-time Window
    .window(Session.withGap("10.minutes").on("rowtime").as("w"));
    // Session Processing-time Window (assuming a processing-time attribute "proctime")
    .window(Session.withGap("10.minutes").on("proctime").as("w"));

Over Window

Over Window和標準SQL中提供的Over語法功能類似,也是一種數據聚合計算的方式,但和Group Window不同的是,Over Window不需要對輸入數據按照窗口大小進行堆疊。Over Window是基於當前數據和其周圍鄰近範圍內數據進行聚合統計的,例如基於當前記錄前面的20條數據,然後基於這些數據統計某一指標的聚合結果。

Table API中,Over Window也是在window方法中指定,但後面不需要和groupBy操作符綁定,後面直接接SELECT操作符,並在select操作符中指定需要查詢字段和聚合指標。

Table table = input
  .window([OverWindow w].as("w"))           // define over window with alias w
  .select("a, b.sum over w, c.min over w"); // aggregate over the over window w
方法 需要 描述
partitionBy 可 選的 定義一個或多個屬性上的輸入分區。每個分區都是單獨排序的,聚合函數分別應用於每個分區。
**注意:**在流式環境中,如果窗口包含partition by子句,則只能並行計算窗口聚合。沒有partitionBy(...)流由單個非並行任務處理。
orderBy 需要 定義每個分區中行的順序,從而定義聚合函數應用於行的順序。
**注意:**對於流式查詢,這必須是聲明的事件時間或處理時間屬性。目前,僅支持單個排序屬性。
preceding 可選的 定義窗口中包含的行的間隔,並在當前行之前。間隔可以指定爲時間或行計數間隔。在窗口上限定具有間隔的大小,例如,10.minutes時間間隔或10.rows行計數間隔。使用常量(即,UNBOUNDED_RANGE時間間隔或UNBOUNDED_ROW行計數間隔)指定在窗口無界限。在Windows上無限制地從分區的第一行開始。如果preceding條款被省略,UNBOUNDED_RANGE並且CURRENT_RANGE被用作默認precedingfollowing用於該窗口。
following 可選的 定義窗口中包含的行的窗口間隔,並跟隨當前行。必須在與前一個間隔(時間或行計數)相同的單位中指定間隔。目前,不支持在當前行之後包含行的窗口。相反,您可以指定兩個常量之一:CURRENT_ROW 將窗口的上限設置爲當前行。CURRENT_RANGE 設置窗口的上限以對當前行的排序鍵進行排序,即窗口中包含與當前行具有相同排序鍵的所有行。如果following省略該子句,則將時間間隔窗口CURRENT_RANGE的上限定義爲,並將行計數間隔窗口的上限定義爲CURRENT_ROW
as 需要 爲覆蓋窗口指定別名。別名用於引用以下select()子句中的over window 。

Note : 目前,同一select()調用中的所有聚合函數必須計算相同的窗口。

Unbounded Over Windows

// Unbounded Event-time over window (assuming an event-time attribute "rowtime")
.window(Over.partitionBy("a").orderBy("rowtime").preceding("unbounded_range").as("w"));

// Unbounded Processing-time over window (assuming a processing-time attribute "proctime")
.window(Over.partitionBy("a").orderBy("proctime").preceding("unbounded_range").as("w"));

// Unbounded Event-time Row-count over window (assuming an event-time attribute "rowtime")
.window(Over.partitionBy("a").orderBy("rowtime").preceding("unbounded_row").as("w"));

// Unbounded Processing-time Row-count over window (assuming a processing-time attribute "proctime")
.window(Over.partitionBy("a").orderBy("proctime").preceding("unbounded_row").as("w"));

Bounded Over Windows

// Bounded Event-time over window (assuming an event-time attribute "rowtime")
.window(Over.partitionBy("a").orderBy("rowtime").preceding("1.minutes").as("w"))

// Bounded Processing-time over window (assuming a processing-time attribute "proctime")
.window(Over.partitionBy("a").orderBy("proctime").preceding("1.minutes").as("w"))

// Bounded Event-time Row-count over window (assuming an event-time attribute "rowtime")
.window(Over.partitionBy("a").orderBy("rowtime").preceding("10.rows").as("w"))

// Bounded Processing-time Row-count over window (assuming a processing-time attribute "proctime")
.window(Over.partitionBy("a").orderBy("proctime").preceding("10.rows").as("w"))

Row-based Operations(基於行操作)

The row-based operations generate outputs with multiple columns.

Operators Describtion
Map 使用用戶定義的標量函數或內置標量函數執行映射操作。如果輸出類型是複合類型,則輸出將被展平。在這裏插入圖片描述
FlatMap 在這裏插入圖片描述
Aggregate 在這裏插入圖片描述
FlatAggregate 在這裏插入圖片描述
Group Window FlatAggregate 在這裏插入圖片描述

數據類型

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章