我试图将ApacheSpark结构化流连接到MQTT主题(在这种情况下,IBM Bluemix上的IBM Watson IoT平台)。
我按如下方式创建结构化流:
val df = spark.readStream
.format("org.apache.bahir.sql.streaming.mqtt.MQTTStreamSourceProvider")
.option("username","a-vy0z2s-q6s8r693hv")
.option("password","B+UX(aWuFPvX")
.option("clientId","a:vy0z2s:a-vy0z2s-zfzzckrnqf")
.option("topic", "iot-2/type/WashingMachine/id/Washer02/evt/voltage/fmt/json")
.load("tcp://vy0z2s.messaging.internetofthings.ibmcloud.com:1883")
到目前为止一直很好,在REPL中我得到了这个df对象如下:
df:org.apache.spark.sql.DataFrame = [value:string,timestamp: 时间戳]
我从this thread了解到每次连接时都必须更改客户端ID。所以这已经解决了,但如果我开始使用这一行从流中读取:
val query = df.writeStream。输出outputmode("附加&#34)
。 格式("控制台&#34)。启动()
然后生成的架构如下所示:
df:org.apache.spark.sql.DataFrame = [value:string,timestamp:timestamp]
数据如下:
这意味着我的JSON流被转换为包含JSON表示的字符串对象流。
这是ApacheBahir的限制吗?
同样提供架构也没有帮助,因为以下代码类似于相同的结果:
import org.apache.spark.sql.types._
val schema = StructType(
StructField("count",LongType,true)::
StructField("flowrate",LongType,true)::
StructField("fluidlevel",StringType,true)::
StructField("frequency",LongType,true)::
StructField("hardness",LongType,true)::
StructField("speed",LongType,true)::
StructField("temperature",LongType,true)::
StructField("ts",LongType,true)::
StructField("voltage",LongType,true)::
Nil)
:paste
val df = spark.readStream
.schema(schema)
.format("org.apache.bahir.sql.streaming.mqtt.MQTTStreamSourceProvider")
.option("username","a-vy0z2s-q6s8r693hv")
.option("password","B+UX(a8GFPvX")
.option("clientId","a:vy0z2s:a-vy0z2s-zfzzckrnqf4")
.option("topic", "iot-2/type/WashingMachine/id/Washer02/evt/voltage/fmt/json")
.load("tcp://vy0z2s.messaging.internetofthings.ibmcloud.com:1883")
答案 0 :(得分:1)
许多DataSources
,包括but not limited to MQTTStreamSource
,都有固定的架构,其中包含一条消息和一个时间戳。模式不会丢失,根本不会被解析,这是预期的行为。
如果架构已修复并且预先知道,则应该能够使用from_json
函数:
import org.apache.spark.sql.functions.from_json
df.withColumn("value", from_json($"value", schema))
答案 1 :(得分:0)
对于解析(因为我不再使用“from_json”方法)我已经使用了
import org.apache.spark.sql.functions.json_tuple
以及以下代码,它也有效:
df.withColumn( “值”,json_tuple($ “值”, “myColumnName”))