在Spark

时间:2018-06-02 22:32:26

标签: java apache-spark arraylist filter apache-spark-dataset

我有"会话" Spark中的数据集:

Dataset<Row> sessions

这是架构:

 |-- session_id: string (nullable = true)
 |-- screens: array (nullable = true)
 |    |-- element: struct (containsNull = true)
 |    |    |-- load_time: long (nullable = true)
 |    |    |-- name: string (nullable = true)
 |-- session_start: boolean (nullable = true)

我可以按&#34; session_start&#34;过滤记录它按预期工作:

Dataset<Row> startedSessions =  sessions.filter(col("session_start").equalTo("true"));

我希望以类似方式过滤会话,但按字段过滤&#34; screens.name&#34; (嵌套字段),但不仅针对单个值,还要检查其值是否在预定义ArrayList中。 换句话说,假设我们有Araylist&#34; desiredValues&#34;我需要所有记录,其中&#34; screens.name&#34;在&#34;期望值&#34;数组列表。

请用Java来解决这个问题。提前谢谢!

更新:感谢您的建议,我尝试在评论中提出的How to use Column.isin in Java?解决方案,我的陈述现在看起来像这样:

List<String> desiredValues = new ArrayList<String>(Arrays.asList("login", "logout"));
Dataset<Row> matchingSessions = sessions.filter(col("screens.name").isin(desiredValues.stream().toArray(String[]::new)));

然而,现在我收到了这个错误:

org.apache.spark.sql.AnalysisException: cannot resolve '(`screens`.`name` IN ('login', 'logout'))' due to data type mismatch: Arguments must be same type;;
'Filter screens#149.name IN (login,logout)

即使通过&#34; screens.name&#34; &#34; desiredValues&#34;是字符串。

更新:经过进一步研究后,我发现Spark可能不支持过滤&#34; array&#34;字段(在我的情况下&#34; screens.name&#34;)包含所需值的数组(在我的情况下&#34; desiredValues&#34;)。换句话说,我们可能只有&#34; array&#34;字段按单值过滤:

Dataset<Row> matchingSessions =  sessions.filter(array_contains(col("screens.name"), "login"));

或由值数组过滤的简单(非嵌套)字段:

List<String> desiredValues = new ArrayList<String>(Arrays.asList("123", "456"));
Dataset<Row> matchingSessions = sessions.filter(col("session_id").isin(desiredValues.stream().toArray(String[]::new)));

0 个答案:

没有答案