我寻找一种方法来检索创建为:
的DStream的第一个元素val dstream = ssc.textFileStream(args(1)).map(x => x.split(",").map(_.toDouble))
不幸的是,dstream上没有采取功能(如在RDD上)//dstream.take(2) !!!
有人可以知道怎么做吗?感谢
答案 0 :(得分:1)
您可以在DStream对象中使用transform方法,然后获取输入RDD的n个元素并将其保存到列表中,然后过滤原始RDD以包含在此列表中。这将返回一个包含n个元素的新DStream。
val n = 10
val partOfResult = dstream.transform(rdd => {
val list = rdd.take(n)
rdd.filter(list.contains)
})
partOfResult.print
答案 1 :(得分:1)
之前建议的解决方案没有为我编译,因为 take()方法返回一个不可序列化的数组,因此Spark流将失败并带有 java.io.NotSerializableException
以前代码的一个简单变体对我有用:
val n = 10
val partOfResult = dstream.transform(rdd => {
rdd.filter(rdd.take(n).toList.contains)
})
partOfResult.print
答案 2 :(得分:0)
共享对我有用的基于Java的解决方案。想法是使用自定义函数,该函数可以从已排序的RDD发送第一行。
someData.transform(
rdd ->
{
JavaRDD<CryptoDto> result =
rdd.keyBy(Recommendations.volumeAsKey)
.sortByKey(new CryptoComparator()).values().zipWithIndex()
.map(row ->{
CryptoDto purchaseCrypto = new CryptoDto();
purchaseCrypto.setBuyIndicator(row._2 + 1L);
purchaseCrypto.setName(row._1.getName());
purchaseCrypto.setVolume(row._1.getVolume());
purchaseCrypto.setProfit(row._1.getProfit());
purchaseCrypto.setClose(row._1.getClose());
return purchaseCrypto;
}
).filter(Recommendations.selectTopinSortedRdd);
return result;
}).print();
自定义函数selectTopinSortedRdd
如下所示:
public static Function<CryptoDto, Boolean> selectTopInSortedRdd = new Function<CryptoDto, Boolean>() {
private static final long serialVersionUID = 1L;
@Override
public Boolean call(CryptoDto value) throws Exception {
if (value.getBuyIndicator() == 1L) {
System.out.println("Value of buyIndicator :" + value.getBuyIndicator());
return true;
}
else {
return false;
}
}
};
它基本上比较所有传入的元素,并且仅对已排序的RDD中的第一条记录返回true
。
答案 3 :(得分:0)
这似乎一直是DStreams和常规RDD的问题。
如果您不希望(或不能)使用.take()(尤其是在DStreams中),则可以在此处跳出框框,而只需使用reduce即可。这对于DStreams和RDD都是有效的函数。
考虑一下。如果您这样使用reduce(Python示例):
.reduce( lambda x, y : x)
然后发生的是:每传入2个元素,始终仅返回第一个。因此,如果RDD或DStream中有一百万个元素,它将最终缩小到一个元素,这是RDD或DStream中的第一个元素。
简单干净。
但是请记住,.reduce()
没有考虑顺序。但是,您可以使用自定义函数轻松解决此问题。
示例:假设您的数据看起来像x =(1,[1,2,3])和y =(2,[1,2])。元组x,其中第二个元素是一个列表。例如,如果按最长列表进行排序,则您的代码可能如下所示(根据需要进行调整):
def your_reduce(x,y):
if len(x[1]) > len(y[1]):
return x
else:
return y
yourNewRDD = yourOldRDD.reduce(your_reduce)
因此,您将得到'(1,[1,2,3])',因为该列表较长。你去了!
在过去,这使我有些头疼,直到我最终尝试为止。希望这会有所帮助。