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

Apache spark SparkSql查询从cassandra获取定义值的上一行和下一行,apache-spark,cassandra,apache-spark-sql,Apache Spark,Cassandra,Apache Spark Sql,我们必须编写一个SparkSQL查询来获取特定值的上一行和下一行。 比方说,我们在Cassandra中的表结构如下所示 id, timestamp 1, 100 2,200 3,300 4,400 2,200 4,400 现在我必须编写一个Spark查询来只获取两行,在这两行中,第一行的值应该小于300,即(2200),第二行的值应该大于300,即(4400)。由于数据量大,我不想按操作执行订单。如果数据量大,操作的顺序将变慢。 我们可以这样理解需求,假设我想要两个从时间戳值为的表中获取上一

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

id, timestamp
1, 100
2,200
3,300
4,400
2,200
4,400
现在我必须编写一个Spark查询来只获取两行,在这两行中,第一行的值应该小于300,即(2200),第二行的值应该大于300,即(4400)。由于数据量大,我不想按操作执行订单。如果数据量大,操作的顺序将变慢。 我们可以这样理解需求,假设我想要两个从时间戳值为的表中获取上一行和下一行:- 对于第一行:应小于300,因此预期行为(2200) 对于第二行:应大于300,因此预期行为(4400) 输出应该如下所示

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

但这应该在不按操作排序的情况下执行。

您可以使用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联接:

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|
+---+---+---------+-----------+------------------+-------+--------------+

所有这些DFs上的内部联接都会导致“上一个”和“下一个”侧缺少一些条目。但是,如果您只想查看上一条记录或下一条记录,可以逐个执行联接。

上一条记录和下一条记录是什么意思?它是基于
id
上的订单还是基于
时间戳上的订单?或者它是基于DF中记录的当前顺序(这可能是不可预测的)?行按时间戳字段按升序排列。我想得到:1,一行的时间戳值小于300,因此在输出结果中它应该返回(2200)2。还有一行的时间戳值大于300,所以在输出中它应该返回(4400),这应该在没有操作顺序的情况下完成。因为cassandra表中的数据太大。所以我们不能按操作执行订单。谢谢您的回答…但这对Cassandra表中的大数据有好处吗?因为在我们的例子中,我们将从卡夫卡获得1行lac行,然后我们必须执行相同的操作(从卡夫卡的每一行中获得上一行和下一行)@RajendraJangir如果这是在如此精细的级别上完成的,那么为什么要在spark中开始呢?使用一个普通的Java/Scala/etc程序,可以根据需要获取记录,这样做会容易得多。。。对吗?另外,数据来源于卡夫卡,难道你不能使用spark streaming和内置的滑动窗口功能吗?是的,你是对的。非常感谢您的宝贵回答和建议。