import org.apache.flink.api.scala.{DataSet, ExecutionEnvironment} |
- 导入 Flink 的 Scala API 中所需的数据集(DataSet)和执行环境(ExecutionEnvironment)的类型。
scala复制代码
import org.apache.flink.core.fs.FileSystem.WriteMode |
- 导入 Flink 文件系统的写模式(WriteMode),它用于控制写入文件时的行为(例如是否覆盖文件)。
scala复制代码
object dataDR { |
- 定义一个名为 dataDR 的 Scala 对象。
scala复制代码
def main(args: Array[String]): Unit = { |
- 定义程序的入口点 main 方法,它接受一个字符串数组作为参数,并返回 Unit(即无返回值)。
scala复制代码
val env:ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment |
- 创建一个 Flink 执行环境(ExecutionEnvironment)。这是所有 Flink 程序的起点,它提供了设置作业、创建数据源和数据集等操作的方法。
scala复制代码
val inputDataSetA = env.readTextFile("C:\\Users\\91541\\Desktop\\file_A.txt") |
- 从指定的文件路径读取文本文件,并创建一个包含文件内容的 DataSet[String]。这里读取的是 file_A.txt 文件。
scala复制代码
val inputDataSetB = env.readTextFile("C:\\Users\\91541\\Desktop\\file_B.txt") |
- 同样地,从另一个指定的文件路径读取文本文件,并创建另一个 DataSet[String]。这里读取的是 file_B.txt 文件。
scala复制代码
val set3:DataSet[String] = inputDataSetA.union(inputDataSetB) | |
.distinct() |
- 对 inputDataSetA 和 inputDataSetB 进行合并(union),然后去除合并后数据集中的重复元素(distinct)。结果保存在 set3 变量中。
scala复制代码
set3.print() |
- 将 set3 数据集中的元素打印到控制台。这通常用于调试目的,以查看数据集中的内容。
scala复制代码
set3.writeAsText("C:\\Users\\91541\\Desktop\\file_C.txt",writeMode = WriteMode.OVERWRITE).setParallelism(1) |
- 将 set3 数据集的内容写入指定的文本文件。这里使用了 writeAsText 方法,并指定了写模式为 OVERWRITE(即如果文件已存在,则覆盖它)。此外,还设置了并行度为 1,以确保写入操作是顺序执行的,避免在输出目录中创建多个文件。
scala复制代码
env.execute("数据合并去重") |
- 提交 Flink 作业以执行。execute 方法会启动 Flink 集群上的计算,并等待作业完成。这里传入的字符串 "数据合并去重" 是作业的名称,用于在 Flink 的 Web UI 或日志中标识该作业。
scala复制代码
} |
- main 方法的结束。
scala复制代码
} |
- dataDR 对象的结束。
注意:在 Flink 程序中,通常使用 env.execute() 调用作为程序的最后一行,以确保在 main 方法退出之前 Flink 作业能够正确执行和完成。此外,如果您的程序涉及到并行执行,还需要确保数据的分区和并行化操作得当,以实现高效的计算。在这个简单的例子中,由于设置了并行度为 1,所有的操作都是顺序执行的。
3
这段代码是使用 Apache Flink 的 Scala API 来处理两个 CSV 文件中的数据,并计算学生的总分和平均分。下面是对每一行代码的中文解释:
scala复制代码
case class score1(sclass:String, id:Long, name:String, Score_Math:Int, Score_Prog:Int, Score_La:Int, Score_Phy:Int, Score_History:Int, | |
Score_Miltary:Int, Score_AIDS:Int, Score_PE:Int, Score_tutor:Int, Score_C:Int, Score_Politics:Int, Score_English:Int) |
定义了一个名为 score1 的 case class,用于表示 CSV 文件1中的学生数据。
scala复制代码
case class score2(sclass:String, id:Long, name:String, Score_Math2:Int,Score_English2:Int, Score_Phy2:Int, Score_PhyE:Int, Score_SC:Int, Score_SCE:Int, | |
Score_Politics2:Int,Score_PE:Int,Score_DLD:Int,Score_DLDE:Int, Score_Politics3:Int) |
定义了一个名为 score2 的 case class,用于表示 CSV 文件2中的学生数据。
scala复制代码
object tutor { |
定义了一个名为 tutor 的对象。
scala复制代码
def main(args: Array[String]): Unit = { |
定义了 tutor 对象的 main 方法,它是程序的入口点。
scala复制代码
val env:ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment |
创建了一个 Flink 的批处理执行环境 env。
scala复制代码
val inputDataSet1:DataSet[score1] = env.readCsvFile[score1]("C:\\Users\\91541\\Desktop\\chapter6-data1.csv",ignoreFirstLine = true) |
从指定的 CSV 文件路径读取数据,并转换为 score1 类型的数据集 inputDataSet1,同时忽略文件的第一行(通常是标题行)。
scala复制代码
val inputDataSet2:DataSet[score2] = env.readCsvFile[score2]("C:\\Users\\91541\\Desktop\\chapter6-data2.csv",ignoreFirstLine = true) |
从另一个 CSV 文件路径读取数据,并转换为 score2 类型的数据集 inputDataSet2,同样忽略文件的第一行。
scala复制代码
val set1 = inputDataSet1 | |
.map(x => (x.sclass,x.id,x.name,x.Score_AIDS+x.Score_C+x.Score_English+x.Score_History+x.Score_La+x.Score_Math+x.Score_Miltary+x.Score_PE+x.Score_Phy+x.Score_Politics | |
+x.Score_Prog+x.Score_tutor)) |
对数据集 inputDataSet1 进行映射操作,计算每个学生的总分(所有科目分数之和),并将结果存储在新的数据集 set1 中。
scala复制代码
val set2 = inputDataSet2 | |
.map(y => (y.id,y.Score_Math2+y.Score_DLD+y.Score_DLDE+y.Score_English2+y.Score_PE+y.Score_Phy2+y.Score_PhyE+y.Score_Politics2+y.Score_Politics3+y.Score_SC+y.Score_SCE)) |
对数据集 inputDataSet2 进行映射操作,计算每个学生的总分(仅针对该数据集中的科目),并将结果(包括学号和总分)存储在新的数据集 set2 中。
scala复制代码
val UN = set1.join(set2).where(1).equalTo(0) | |
.map( in => (in._1._1,in._1._2,in._1._3,((in._1._4+in._2._2)/23.00).formatted("%.2f"))) | |
.sortPartition(3,Order.DESCENDING) | |
.setParallelism(1) | |
.first(5) |
通过 join 操作将 set1 和 set2 根据学号连接起来,并计算每个学生的平均分(总分除以23,假设总共有23个科目)。结果通过映射操作格式化为保留两位小数的字符串。然后,根据平均分降序排序每个分区内的数据,设置并行度为1,最后取出前5条记录。
scala复制代码
UN.print() |
将计算得到的前5个学生的平均分打印到控制台。
整个程序
4
这段代码是使用 Apache Flink 的 Scala API 来计算两个数据集之间的欧几里得距离。下面是每一行代码的中文解释:
scala复制代码
val env:ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment |
创建了一个 Flink 的批处理执行环境 env,它是执行 Flink 作业的入口点。
scala复制代码
//2.读取数据 |
这是一个注释,表示接下来将读取数据。
scala复制代码
val positions1:DataSet[Tuple2[Integer,Integer]] = env.fromElements( | |
(1,2),(2,4),(3,5)) |
创建了一个名为 positions1 的数据集,它包含三个二维坐标点(整数类型),每个点是一个 (x, y) 坐标对。
scala复制代码
val positions2:DataSet[Tuple2[Integer,Integer]] = env.fromElements( | |
(1,10),(2,12)) |
创建了一个名为 positions2 的数据集,它包含两个二维坐标点,同样每个点是一个 (x, y) 坐标对。
scala复制代码
//3处理数据 获取欧几里得距离 |
这是一个注释,表示接下来将处理数据并计算欧几里得距离。
scala复制代码
val result = |
声明了一个名为 result 的变量,用于存储计算得到的欧几里得距离结果。
scala复制代码
positions1.cross(positions2) |
使用 cross 操作对 positions1 和 positions2 两个数据集进行笛卡尔积运算,生成一个包含所有点对的组合的新数据集。
scala复制代码
.map( in => ("第一个点:("+in._1._1,in._1._2+")"+"\t第二个点("+in._2._1,in._2._2+") 距离:"+ | |
math.sqrt(math.pow(in._1._1 - in._2._1,2)+math.pow(in._1._2-in._2._2,2)).formatted("%.2f"))) |
使用 map 操作对笛卡尔积的结果进行遍历,对于每一对点,计算它们的欧几里得距离,并将计算结果格式化为字符串。字符串包含了两个点的坐标以及它们之间的距离(保留两位小数)。
5
这段代码是使用 Apache Flink 的 Scala API 来处理一个 CSV 文件中的数据,并区分理科学生和文科学生,分别计算他们的总成绩并进行排名。以下是每一行代码的中文解释:
scala复制代码
val env = ExecutionEnvironment.getExecutionEnvironment |
创建一个 Flink 批处理环境的实例,这是执行 Flink 作业的起点。
scala复制代码
val filePath = "C:\\Users\\91541\\Desktop\\chapter6-data3.csv" |
定义 CSV 文件的路径。
scala复制代码
val inputData: DataSet[score3] = env.readCsvFile[score3](filePath, ignoreFirstLine = true) |
从定义的路径读取 CSV 文件,并解析为 score3 类型的 DataSet。这里假设 score3 是一个已经定义好的 Scala case class,用于表示 CSV 文件中的每一行数据。ignoreFirstLine = true 表示忽略文件的第一行(通常是标题行)。
scala复制代码
// 区分理科学生并计算总成绩排名 | |
val SCresult = inputData |
开始处理数据以区分理科学生并计算他们的总成绩排名。
scala复制代码
.filter(in => in.Math!= 0 || in.English != 0 || in.Chinese != 0 || in.Phy != 0 || in.Che != 0 || in.Bio != 0 || in.Policy != 0 || in.History != 0 || in.Geo != 0) // 过滤缺考学生 |
过滤掉至少有一门成绩为 0 的学生(即缺考的学生)。
scala复制代码
.filter(in => in.History == 0 && in.Policy == 0 && in.Geo == 0) // 过滤文科学生 |
进一步过滤出理科学生,即历史、政治和地理成绩都为 0 的学生。
scala复制代码
.map(in => (in.name, in.id, (in.Math + in.English + in.Chinese + in.Phy + in.Che + in.Bio))) // 计算理科成绩 |
计算理科学生的总成绩(数学、英语、语文、物理、化学、生物成绩之和),并返回包含学生姓名、学号和总成绩的元组。
scala复制代码
.sortPartition(2, Order.DESCENDING) // 排序 |
在每个分区内对总成绩进行降序排序。
scala复制代码
.setParallelism(1) |
设置作业的并行度为 1,即所有操作都将在单个任务中执行。
scala复制代码
// 区分文科学生并计算总成绩排名 | |
val ARTresult = inputData |
开始处理数据以区分文科学生并计算他们的总成绩排名。
接下来的几行代码与理科学生的处理类似,但过滤条件和计算总成绩的方式不同,这里不再重复解释。
scala复制代码
println("理科学生成绩如下:") | |
println("姓名\t\t学号\t\t总分\t") | |
SCresult.print() |
打印理科学生的成绩信息,包括姓名、学号和总成绩。
scala复制代码
println("文科学生成绩如下:") | |
println("姓名\t\t学号\t\t总分\t") | |
ARTresult.print() |