Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Apache spark 在Spark中对可重复值进行排序_Apache Spark - Fatal编程技术网

Apache spark 在Spark中对可重复值进行排序

Apache spark 在Spark中对可重复值进行排序,apache-spark,Apache Spark,假设我有以下输入数据: ["example.com", Date(2000, 1, 1)] : 100, ["example.com", Date(2000, 2, 1)]: 30, ["example.com", Date(2000, 3, 1)]: 5, ["xyz.com", Date(2000, 1, 1)]: 20, ["xyz.com", Date(2000, 2, 1)]: 10, ["xyz.com", Date(2000, 3, 1)]: 60] 我想按日期分组(降序),然

假设我有以下输入数据:

["example.com", Date(2000, 1, 1)] : 100,
["example.com", Date(2000, 2, 1)]: 30,
["example.com", Date(2000, 3, 1)]: 5, 
["xyz.com", Date(2000, 1, 1)]: 20,
["xyz.com", Date(2000, 2, 1)]: 10,
["xyz.com", Date(2000, 3, 1)]: 60]
我想按日期分组(降序),然后按计数排序,给我每个日期的域的有序列表

我想以以下方式结束:

Date(2000, 1, 1), [["example.com", 100], ["xyz.com", 20]]
Date(2000, 2, 1), [["example.com", 30], ["xyz.com", 10]]
Date(2000, 3, 1), [["xyz.com", 60], ["example.com", 5]]
这似乎是一个正常的用例,但我在《编程指南》中找不到这样做的方法

我可以
map
[[domain,date]count]->[date,[domain,count]]

这将给我
(K,V)

Date(2000, 1, 1), ["example.com", 100],
Date(2000, 2, 1), ["example.com", 30],
Date(2000, 3, 1), ["example.com", 5], 
Date(2000, 1, 1), ["xyz.com", 20],
Date(2000, 2, 1), ["xyz.com", 10],
Date(2000, 3, 1), ["xyz.com", 60]
[Date(2000, 1, 1), [["example.com", 100], ["xyz.com", 20]]
[Date(2000, 2, 1), [["example.com", 30], ["xyz.com", 10]]
[Date(2000, 3, 1), [["example.com", 5], ["xyz.com", 60]]
然后
groupByKey
,给我
(K,Iterable)

Date(2000, 1, 1), ["example.com", 100],
Date(2000, 2, 1), ["example.com", 30],
Date(2000, 3, 1), ["example.com", 5], 
Date(2000, 1, 1), ["xyz.com", 20],
Date(2000, 2, 1), ["xyz.com", 10],
Date(2000, 3, 1), ["xyz.com", 60]
[Date(2000, 1, 1), [["example.com", 100], ["xyz.com", 20]]
[Date(2000, 2, 1), [["example.com", 30], ["xyz.com", 10]]
[Date(2000, 3, 1), [["example.com", 5], ["xyz.com", 60]]
然后如何在键内进行排序

请原谅伪代码,我正在使用Flambo Clojure包装器,我不想仅仅为了问这个问题而用Java重写它

编辑:每个Iterable(即域列表)可能太大,无法放入内存


EDIT2:这都是伪代码。我使用月份名称使其可读,但为了清晰起见,我已将其改为真实日期。

在大范围内,我将执行以下操作。(可能不是100%正确,因为我没有编译它,但很接近。)为了简单起见,我假设您从一个
RDD[((String,String,Int)]
开始

首先,
groupBy
使用以下内容显示月份:

.groupBy { case ((_, month), _) => month }
并在值中去掉月份:

.mapValues(_.map { case ((domain, _), count) => (domain, count) })
如果需要按月订购,请定义月份的订购:

def monthOfYear(month: String): Int = 
  month match {
     case "January" => 1
     case "February" => 2
     ...
  }
并按月对RDD进行排序:

.sortBy { case (month, _) => monthOfYear(month) }
并按递减计数对域进行排序:

.mapValues(_.toSeq.sortBy{ case (domain, count) => count }(Ordering[Int].reverse))
.sortBy(p => p._2, false)
这既直接又有效,但存在一个问题,即一个月内的所有域计数对都必须适合内存

相反,您可以通过按计数降序排序来重新开始:

.mapValues(_.toSeq.sortBy{ case (domain, count) => count }(Ordering[Int].reverse))
.sortBy(p => p._2, false)

然后按月分组。我还没有对此进行测试,我也不认为这种行为是有保证的,但我希望在实践中,即使在分组之后,元素也会按计数顺序出现。

它们不适合内存。谢谢您的回答。正如我所说的,我不认为域列表将适合内存,我想利用Spark的设施来做到这一点。此外,我几乎100%确信,在一个团队中,订单不会被保留。哦,还有,月份是真实的(可比较的)日期。我只是想说明一下。好吧,忘了日期那部分。嗯,如果您真正的最终目标只是按计数排名前N,那么您可以使用
combineByKey
来实现这一目标,而不会出现内存问题。