2016-02-05 49 views
4

嗨我想从文本文件中使用spark读取特定的行。如何从sparkContext读取特定行

SparkConf conf = new SparkConf().setAppName(appName).setMaster(master); 
sc = new JavaSparkContext(conf); 
JavaRDD<String> lines = sc.textFile("data.txt"); 
String firstLine = lines.first(); 

它可以使用.first()命令来获取data.text文档的第一行。我如何访问文档的第N行?我需要Java解决方案。

回答

4

Apache Spark RDD并不打算用于查找。获得n th线的最“有效”的方式是lines.take(n + 1).get(n)。每当你这样做,它会读取文件的第一行n行。您可以运行lines.cache以避免这种情况发生,但它仍然会通过网络以非常低效的舞蹈移动第一条线路上的第一条n线路。

如果数据可以放在一台机器上,只收集一次,并在本地访问:List<String> local = lines.collect(); local.get(n);

如果数据不适合一台机器,则需要一个支持高效查找的分布式系统。流行的例子是HBase和Cassandra。

也有可能您的问题可以通过Spark高效解决,但不能通过查找解决。如果你在一个单独的问题中解释更大的问题,你可能会得到这样的解决方案。 (查找在单机应用非常普遍,但分布式算法有不同的想法。)

+0

如果你使用DataFrames进行获取路线,我认为你需要'lines.take(n).apply(n-1)' –

+0

谢谢,我以某种方式解决了这个问题。假设“'n'th”是基于零的:)。 'lines'应该是'JavaRDD',所以'take'会返回一个Java'List ',因此'get'而不是'apply'。 –

1

我觉得这是快,因为它得到

def getNthLine(n: Long) = 
    lines.zipWithIndex().filter(_._2 == n).first 
1

像@Daniel Darabos说,RDDS没有索引的线看起坐,所以另一种方法是给它一个指标:

lines.zipWithIndex.filter(_._2==n).map(_._1).first() 

给它一个索引,然后第一个再次使用火花背景下,但这种方法有些什么效率低下,傻时的大小你RDD很小。但是,当RDD的大小非常大时,将其收集到主人会变得效率低下(并且可能会限制内存),并且此方法将成为更好的选择。