apache-spark - SparkSql 查询以从 cassandra 获取定义值的上一行和下一行
问题描述
我们必须编写一个 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
但这应该不按操作顺序执行。
解决方案
您可以使用 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 上的内部连接会导致“上一个”和“下一个”两侧的某些条目丢失。但是,如果您有兴趣查看前一个或下一个记录,您可以执行一个接一个的连接。
推荐阅读
- python - 如何标准化 unix 时间戳以求和为离散数值?
- python - Airflow DAG 中使用的连接未提供 _decrypted_ 密码或额外密码 - DAG 创作问题
- google-apps-script - 将 Apps 脚本功能应用于 Google 表格中的其他行
- javascript - 如何获得简单的日期(“月数”)?
- python - Errors in ChromeDriver logs using a proxy through Selenium and Python
- visual-studio - Is there a way to append query string to the publish URL when publishing an app via ClickOnce
- go - Elastic term query appending array inside array in golang
- c++ - In C++, is it possible for child classes of an abstract class to take different parameters for the same fuctions?
- c# - My audio player on Android doesn't work - Xamarin
- typescript - Convert {number, Observable
} to Observable