首页 文章

使用spark cassandra连接器在多个群集列上运行范围查询时出错:

提问于
浏览
0

以下是cassandra表模式:

CREATE TABLE my_table(年份文本,月份文本,日期文本,小时int,min int,sec int,PRIMARY KEY((年,月,日),小时,分钟,秒))

如果我使用cassandra cql运行以下查询,它可以工作:

SELECT * FROM my_table WHERE year ='2017' and month ='01' and day ='16' and (hour,min,sec) > (1,15,0) LIMIT 200

但是,当我使用spark-cassandra连接器运行相同的查询时,它不起作用:

sparkSession.read().format("org.apache.spark.sql.cassandra").options(map).load()
                .where(year ='2017' and month ='01' and day ='16' and (hour,min,sec) >= (1,15,0)");

我在日志中遇到以下异常:

> Exception in thread "main" org.apache.spark.sql.AnalysisException:
> cannot resolve '(struct(`hour`, `min`, `sec`) >= struct(1, 15, 0))'
> due to data type mismatch: differing types in '(struct(`hour`, `min`,
> `sec`) >= struct(1, 15, 0))'  and (struct<hour:int,min:int,sec:int>
> struct<col1:int,col2:int,col3:int>).; line 1 pos 96

Spark-cassandra-connector版本:2.0.0-M3

火花版本:2.0.0

任何帮助深表感谢

1 回答

  • 1

    很简单,CQL不兼容Spark Sql或Catalyst . 你所看到的是语法上的冲突 .

    这个where子句:

    .where(year ='2017' and month ='01' and day ='16' and (hour,min,sec) >= (1,15,0)
    

    不是直接推到 Cassandra . 相反,它正在转变为催化剂谓词 . 这是你遇到问题的地方

    Cataylst看到了这一点

    (hour,min,sec) >= (1,15,0)
    

    并尝试为他们制作类型

    左手边变成了

    struct<hour:int,min:int,sec:int>
    

    右手边变成了

    struct<col1:int,col2:int,col3:int>
    

    这些不是元组,而是明确键入的结构 . 他们不能直接比较你的错误 . 在DataFrame api中,您只需使用正确的类型定义一个新的Struct并制作一个文字,但我不确定如何在SparkSQL中表达它 .

    无论这个元组谓词都不会被推到Cassandra . 您定义的小时,分钟,秒的结构将从Cassandra隐藏,因为基础表不提供 Struct<hour, min, sec> ,这意味着Spark认为在从Cassandra中提取数据后需要生成它 .

    你最好只使用@AkashSethi提到的 AND 单独的子句

相关问题