SparkSql查询从cassandra获取定义值的上一行和下一行

时间:2018-04-28 07:10:36

标签: apache-spark cassandra apache-spark-sql

我们必须编写一个SparkSQL查询来获取特定值的上一行和下一行。 让我们说,我们在Cassandra的表结构如下所示

id, timestamp
1, 100
2,200
3,300
4,400

现在我必须写一个Spark查询来只获得两行,而在这两行中,第一行的值应该小于300,即(2,200)和第二行的值应该是大于300即(4,400)。而且由于数据量很大,我不想按操作执行订单。在数据量很大的情况下,操作的顺序会很慢。 我们可以理解这样的要求,假设我想要从表格的前一个和下一行获取时间戳值为: - 对于第一行:应小于300,因此预期行为(2,200) 对于第二行:应该大于300,因此预期的行是(4,400) 输出应该如下所示

2,200
4,400

但是这应该在没有操作的情况下执行。

1 个答案:

答案 0 :(得分:1)

您可以使用RDD API,创建一个向上或向下移动的索引列来模拟滑动操作:

#Obtain an index for each element
df_id = df.rdd.zipWithIndex()\
         .map(lambda row: Row(id=row[0].id, timestamp=row[0].timestamp, idx=row[1]))\
         .toDF()
previousDF = df_id.rdd\
          .map(lambda row: Row(previous_id=row.id, previous_timestamp=row.timestamp, idx=row.idx+1))\
          .toDF()
nextDF = df_id.rdd\
          .map(lambda row: Row(next_id=row.id, next_timestamp=row.timestamp, idx=row.idx-1))\
          .toDF()

现在,在idx列上执行联接,将原始DF与其他人联合起来:

df_id.join(previousDF, on='idx')\
     .join(nextDF, on='idx')\
     .show()

结果如下:

+---+---+---------+-----------+------------------+-------+--------------+
|idx| id|timestamp|previous_id|previous_timestamp|next_id|next_timestamp|
+---+---+---------+-----------+------------------+-------+--------------+
|  1|  2|      200|          1|               100|      3|           300|
|  2|  3|      300|          2|               200|      4|           400|
+---+---+---------+-----------+------------------+-------+--------------+

所有这些DF上的内部联接导致"之前的"和" next"两侧。但是,如果您只想查看上一个或下一个记录,则可以执行逐个连接。