过滤掉在 Java 中没有某些嵌套字段的 Spark 数据帧行

时间:2021-07-05 06:31:47

标签: apache-spark apache-spark-sql apache-spark-dataset

我在 spark 数据框中有以下示例行。

{
    "id":"B07H3MVTSN",
    "mid":4,
    "inner":{
      "type1":[{
          "cid":"B06XVVSLX8"
        },
        {
          "cid":"B06XJ2JZ2Z"
        }
      ],
      "type2":[{
          "cid":"B06XVVSLX1"
        },
        {
          "cid":"B06XJ2JZ22"
        }
      ],
      "type3":[{
          "cid":"B06XVVSLX3"
        },
        {
          "cid":"B06XJ2JZ24"
        }
      ]
    }
  }

我有一个字符串列表,可以是 {"type1","type2"}。

我想从数据框中过滤掉(删除)没有这两个字段中的任何一个的行。如何添加 filter() 条件,该条件从列表中的一组值中检查嵌套结构字段的存在

例如下面的示例行应该使用过滤条件删除,因为它不包含 type1 和 type2

{
        "id":"B07H3MVTS1",
        "mid":4,
        "inner":{
          "type3":[{
              "cid":"B06XVVSLX3"
            },
            {
              "cid":"B06XJ2JZ24"
            }
          ]
        }
      }

以上数据的模式可以在下面的方法 getSchema() 中看到

private StructType getSchema(){

        ArrayType types = DataTypes.createArrayType(DataTypes.createStructType(
                new StructField[] {
                        DataTypes.createStructField("cid", DataTypes.StringType, false)
                }));

        StructType inner = DataTypes.createStructType(
                new StructField[] {
                        DataTypes.createStructField("type1", types, true), DataTypes.createStructField("type2", types, true),
                        DataTypes.createStructField("type3", types, true),
                        DataTypes.createStructField("type4", types, true)
                });

        return DataTypes.createStructType(
                new StructField[] {
                        DataTypes.createStructField("id", DataTypes.StringType, false),
                        DataTypes.createStructField("mid", DataTypes.IntegerType, false),
                        DataTypes.createStructField("inner", inner, false)
                });
    }

1 个答案:

答案 0 :(得分:1)

您可以filter使用isNotNull功能的字段列表如下,根据需要调整过滤条件

val fields = List("type1", "type2")

val filter = fields.map(f => col(s"inner.$f").isNotNull).reduce(_ or _)

df.filter(filter).show(false)

输出:

+----------+------------------------------------------------------------------------------------------+---+
|id        |inner                                                                                     |mid|
+----------+------------------------------------------------------------------------------------------+---+
|B07H3MVTSN|{[{B06XVVSLX8}, {B06XJ2JZ2Z}], [{B06XVVSLX1}, {B06XJ2JZ22}], [{B06XVVSLX3}, {B06XJ2JZ24}]}|4  |
+----------+------------------------------------------------------------------------------------------+---+
相关问题