Scala Spark:使用groupByKey创建索引以生成排序的、不同的值列表?
我正在使用Spark创建一个“反向索引”,将一个英文标记映射回找到该标记的DocumentID。鉴于表格的现有数据:Scala Spark:使用groupByKey创建索引以生成排序的、不同的值列表?,scala,apache-spark,Scala,Apache Spark,我正在使用Spark创建一个“反向索引”,将一个英文标记映射回找到该标记的DocumentID。鉴于表格的现有数据: documentId1, token documentId2, token 我想创建键的倒排索引,值形式: token, List(documentId1, documentId2, documentId3, ...) 其中,值是排序为且不同的文档ID列表(唯一) 到目前为止,我的情况如下: // List of (documentId, token) pairs var d
documentId1, token
documentId2, token
我想创建键的倒排索引,值形式:
token, List(documentId1, documentId2, documentId3, ...)
其中,值是排序为且不同的文档ID列表(唯一)
到目前为止,我的情况如下:
// List of (documentId, token) pairs
var data = Array((100, "spark"), (50, "spark"), (50, "spark"), (1, "apache"), (3, "apache"), (2, "apache"))
var myrdd = sc.parallelize(data)
var myrddGrouped = myrdd.map(pair => (pair._2, pair._1)).groupByKey()
// myrddGrouped: org.apache.spark.rdd.RDD[(String, Iterable[Int])] = ShuffledRDD[226] at groupByKey at <console>:31
myrddGrouped.foreach(println)
// (apache,CompactBuffer(1, 3, 2))
// (spark,CompactBuffer(100, 50, 50))
//对(documentId,token)的列表
var数据=数组((100,“spark”),(50,“spark”),(50,“spark”),(1,“apache”),(3,“apache”),(2,“apache”))
var myrdd=sc.parallelize(数据)
var myrddGrouped=myrdd.map(pair=>(pair.\u 2,pair.\u 1)).groupByKey()
//myrddGroup:org.apache.spark.rdd.rdd[(String,Iterable[Int])]=shuffleddd[226]位于groupByKey at:31
myrddGroup.foreach(println)
//(apache,CompactBuffer(1,3,2))
//(火花,小型缓冲器(100,50,50))
如您所见,我使用的是groupByKey(),但结果值是一个CompactBuffer,而不是一个列表。如何对其应用“distinct”和“sort”?我建议将其聚合到一个集合中,而不是使用
groupByKey
。这样,在聚合过程中将消除重复项,然后您可以转换为某种类型的列表
,并应用排序
使用评论中的一些建议,也许类似于以下的方法应该可以奏效:
val input = sc.parallelize(Array((100, "spark"), (50, "spark"), (50, "spark"), (1, "apache"), (3, "apache"), (2, "apache")))
val setRDD = input.map(_.swap).aggregateByKey(Set[Int]())(_ ++ Set(_), _ ++ _)
val sortedListRDD = setRDD.mapValues(_.toList.sorted)
** sortedListRDD.foreach(println)
** (spark,List(50, 100))
** (apache,List(1, 2, 3))
需要注意的是,您应该将RDD声明为
val
,因为它们是不可变的。可以使用新的RDD重新分配var
,但由于您似乎没有这样做,我只会使用val
。我建议聚合到一个集合中,而不是使用groupByKey
。这样,在聚合过程中将消除重复项,然后您可以转换为某种类型的列表
,并应用排序
var data = Array((100, "spark"), (50, "spark"), (50, "spark"), (1, "apache"), (3, "apache"), (2, "apache"))
var myrdd = sc.parallelize(data)
var myrddGrouped = myrdd.map(pair => (pair._2, pair._1)).groupByKey().mapValues(_.toSet.toList).collect
res141: Array[(String, List[Int])] = Array((spark,List(50, 100)), (apache,List(1, 2, 3)))
使用评论中的一些建议,也许类似于以下的方法应该可以奏效:
val input = sc.parallelize(Array((100, "spark"), (50, "spark"), (50, "spark"), (1, "apache"), (3, "apache"), (2, "apache")))
val setRDD = input.map(_.swap).aggregateByKey(Set[Int]())(_ ++ Set(_), _ ++ _)
val sortedListRDD = setRDD.mapValues(_.toList.sorted)
** sortedListRDD.foreach(println)
** (spark,List(50, 100))
** (apache,List(1, 2, 3))
需要注意的是,您应该将RDD声明为val
,因为它们是不可变的。可以使用新的RDD重新分配var
,但由于您似乎没有这样做,我只会使用val
。myrddGrouped.mapValues(u.toSeq.distinct.sorted)
而不是myrdd.map(pair=>(pair.\u 2,pair.\u 1))
您可以简单地使用Tuple2
的swap
方法:myrdd.map(u.swap)
myrddGrouped.mapValues(u.toSeq.distinct.sorted)
而不是myrdd.map(pair=>(pair.u2,pair.rdu.1))
您可以简单地使用Tuple2
的swap
方法
var data = Array((100, "spark"), (50, "spark"), (50, "spark"), (1, "apache"), (3, "apache"), (2, "apache"))
var myrdd = sc.parallelize(data)
var myrddGrouped = myrdd.map(pair => (pair._2, pair._1)).groupByKey().mapValues(_.toSet.toList).collect
res141: Array[(String, List[Int])] = Array((spark,List(50, 100)), (apache,List(1, 2, 3)))