我是Spark的新手。我在HDFS中有两个表。一个表(表1)是一个标签表,由一些文本组成,可以是一些单词或一个句子。另一个表(表2)有一个文本列。每一行在表1中可以有多个关键字。我的任务是找出表1中表2中文本列的所有匹配关键字,并输出表2中每一行的关键字列表。
问题是我必须迭代表2和表1中的每一行。如果我为表1生成一个大列表,并使用表2的映射函数。我仍然需要使用循环来迭代列表在地图功能。并且驱动程序显示JVM内存限制错误,即使循环不是很大(10万次)。
myTag是表1的标签列表。
row1|Spark
row2|RDD
有任何建议要完成这项任务吗?有或没有Spark 非常感谢!
一个例子如下:
表1
row1| Spark is a fast and general engine. RDD supports two types of operations.
row2| All transformations in Spark are lazy.
row3| It is for test. I am a sentence.
表2
row1| Spark,RDD
row2| Spark
预期结果:
row1| Spark
row2| RDD
row3| two words
row4| I am a sentence
主要编辑:
第一个表实际上可能包含句子,而不仅仅是简单的关键字:
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
p {color;blue;}
</style>
</head>
<body>
<p>This text is blue</p>
</body>
</html>
答案 0 :(得分:1)
在这里,考虑您提供的数据样本:
val table1: Seq[(String, String)] = Seq(("row1", "Spark"), ("row2", "RDD"), ("row3", "Hashmap"))
val table2: Seq[String] = Seq("row1##Spark is a fast and general engine. RDD supports two types of operations.", "row2##All transformations in Spark are lazy.")
val rdd1: RDD[(String, String)] = sc.parallelize(table1)
val rdd2: RDD[(String, String)] = sc.parallelize(table2).map(_.split("##").toList).map(l => (l.head, l.tail(0))).cache
我们将构建第二个数据表的倒排索引,我们将加入第一个表:
val df1: DataFrame = rdd1.toDF("key", "value")
val df2: DataFrame = rdd2.toDF("key", "text")
val df3: DataFrame = rdd2.flatMap { case (row, text) => text.trim.split( """[^\p{IsAlphabetic}]+""")
.map(word => (word, row))
}.groupByKey.mapValues(_.toSet.toSeq).toDF("word", "index")
import org.apache.spark.sql.functions.explode
val results: RDD[(String, String)] = df3.join(df1, df1("value") === df3("word")).drop("key").drop("value").withColumn("index", explode($"index")).rdd.map {
case r: Row => (r.getAs[String]("index"), r.getAs[String]("word"))
}.groupByKey.mapValues(i => i.toList.mkString(","))
results.take(2).foreach(println)
// (row1,Spark,RDD)
// (row2,Spark)
主要编辑:
如评论中所述:问题的规格发生了变化。关键字不再是简单的关键字,它们可能是句子。在这种情况下,这种方法不会起作用,这是一种不同的问题。一种方法是使用Locality-sensitive hashing (LSH)算法进行最近邻搜索。
此算法的实现可用here。
遗憾的是,算法及其实现在SO上讨论的时间太长。
答案 1 :(得分:0)
从我的问题陈述中可以收集到的是,您尝试使用表1中的关键字标记表2中的数据。为此,不要将Table1作为列表加载然后执行表2中每行的每个关键字模式匹配,执行以下操作: