繁体   English   中英

迭代 Stream dataframe 中的列值,并使用 Scala 和 Spark 将每个值分配给一个公共列表

[英]Iterate a column values in a Stream dataframe and assign each value to a common list using Scala and Spark

我有以下Stream Dataframe

+------------------------------------+
|______sentence______________________|
| Representative is a scientist      |
| Norman did a good job in the exam  |
| you want to go on shopping?        |
--------------------------------------

我的清单如下

val myList

作为最终的 output 我需要 myList 在 stream dataframe 中包含以上三个句子

output

myList = [Representative is a scientist, Norman did a good job in the exam, you want to go on shopping? ]

我尝试了以下给出 stream 错误

val myList =   sentenceDataframe.select("sentence").rdd.map(r => r(0)).collect.toList

上述方法抛出的错误

org.apache.spark.sql.AnalysisException:必须使用 writeStream.start() 执行带有流源的查询

请注意,上述方法适用于普通数据框,但不适用于 stream dataframe。

有没有办法遍历 stream dataframe 的每一行并使用scala 和 spark将行值分配到公共列表中?

这听起来像是一个非常奇怪的用例,因为 stream 理论上永远不会结束。 你确定你不只是在寻找常见的 spark DataFrames 吗?

如果不是这种情况,您可以做的是使用累加器和火花流 foreachBatch 接收器。 我使用了一个简单的套接字连接来演示这一点。 您可以使用 nc -lp 3030 在 ubuntu 下启动一个简单的套接字服务器,然后将消息传递给 stream,生成的 DataFrame 将具有 [值字符串] 的模式

val acc = spark.sparkContext.collectionAccumulator[String]

val stream = spark.readStream.format("socket").option("host", "localhost").option("port", "3030").load()

val query = stream.writeStream.foreachBatch((df: DataFrame, l: Long) => {
     df.collect.foreach(v => acc.add(v(0).asInstanceOf[String]))
  }).start()

...

// For some reason you are stopping the stream here
query.stop()
val myList = acc.value

现在你可能有一个问题是为什么我们使用累加器而不仅仅是一个 ArrayBuffer。 ArrayBuffers 可以在本地工作,但在集群上,foreachBatch 中的代码可能会在完全不同的节点上执行。 这意味着它不会有任何影响,这也是累加器首先存在的原因(参见https://spark.apache.org/docs/latest/rdd-programming-guide.html#accumulators

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM