我使用以下代码将Spark-Streaming
的输出存储到ElasticSearch
。我想将spark-streaming的输出映射到正确的名称i.e (Key, OsName, PlatFormName, Mobile, BrowserName, Count)
。但正如你可以看到的那样,它在ES中被映射为_1或_2等。
此外,我想在索引ES中的数据之前添加一些过滤器,即(if PlatFormName = "ubuntu" then index the data)
。那么,我该怎么做?
val realTimeAgg = lines.map{ x => ((x.key, x.os, x.platform, x.mobile, x.browser), 1)}.reduceByKey(_+_)
val pageCounts = realTimeAgg.map
pageCounts.foreachRDD{ x =>
if (x.toLocalIterator.nonEmpty) {
EsSpark.saveToEs(x, "spark/ElasticSearch")
}
}
ssc.start()
ssc.awaitTermination()
ElasticSearch中的输出:
{
"_index": "spark",
"_type": "ElasticSearch",
"_id": "AVTH0JPgzgtrAOUg77qq",
"_score": 1,
"_source": {
"_1": {
"_3": "Amiga",
"_2": "AmigaOS 1.3",
"_6": "SeaMonkey",
"_1": "Usedcar",
"_4": 0,
"_5": 0
},
"_2": 1013
}
}
答案 0 :(得分:1)
弹性搜索文档的键是_1,_2等,因为您正在存储具有(Tuple6,Long)数据类型的PairRDD。
要保留密钥,您应该使用案例类作为密钥。
val realTimeAgg = lines.map{ x => (x, 1)}.reduceByKey(_+_)
我假设对象x的类是一个case类,你想使用该类的所有字段进行缩减(即检查2个case类实例的相等性)。如果该类的所有字段都不是要用于相等的类的自然键,那么您有两个选项 -
您可以在写入ElasticSearch之前添加所需的过滤器。
pageCounts.foreachRDD { x =>
if (x.toLocalIterator.nonEmpty) {
val y = x.filter(z => z._1.platform == "ubuntu")
EsSpark.saveToEs(y, "spark/ElasticSearch")
}
}
PS:如果你正在用(case class,Long)案例类测试对RDD,就像我建议使用lines.map(x =>(x,1))。reduceByKey(_ + _)。有一个与Spark Shell特别相关的错误,案例类不能正确地用作减少操作的关键类 - jira issue