如何正确过滤Spark中的期间数据?

时间:2018-12-21 05:06:05

标签: scala apache-spark

我是Spark的新手,需要一些建议。

我的镶木地板上有很多柱子。我想过滤特定手机号码的期间数据。

有以下输入数据:

val dateFrom = "2018-10-01"
val dateTo = "2018-11-05"
val mobile_numbers = "7778529636,745128598,7777533575"

实木复合地板具有以下结构:

| START_DATE          | MOBILE_NUMBER | STATUS | OTHER_COLUMNS
|---------------------|---------------|--------|--------------
| 2018-11-28 20:00:00 | 7778541536    | IN     | ************
| 2018-11-29 00:00:00 | 7786984525    | OUT    | ************
| 2018-11-30 09:00:00 | 7986984525    | IN     | ************
| 2018-12-01 00:30:00 | 7685984425    | OUT    | ************
| 2018-12-02 12:00:00 | 7586984525    | IN     | ************

代码

spark.read.parquet("fs://path/file.parquet").filter(???)

1 个答案:

答案 0 :(得分:2)

我假设您要选择那些属于定义的日期范围并在定义的数字列表中具有MOBILE_NUMBER列值的行。

首先,您必须确保Scala代码中和数据框内的数据具有相同的格式,以便可以正确比较它们。例如:

val dateFrom = "2018-10-01 00:00:00"
val dateTo = "2018-11-05 23:59:59"
val mobileNumbers = Vector("7778529636", "745128598", "7777533575")

请注意,我将移动电话号码表示为字符串,因为对于开头为零的号码,您可能会得到意外的结果。日期也是字符串。

然后您的过滤查询可能如下所示:

import spark.implicits._  // for the $"something" syntax

spark.read.parquet("...")
  .filter(
    $"START_DATE".between(dateFrom, dateTo) && $"MOBILE_NUMBER".isin(mobileNumbers: _*)
  )

理想情况下,日期应采用不允许歧义的格式,例如数字时间戳记,因为否则可能会导致2018-10-01 56:78:90之类的无效值破坏比较,但是在大多数情况下这应该可行,并且如果确实有必要,则可以使用org.apache.spark.sql.functions.udf编写UDF确保它完全正确的方法。