【问题标题】:Cassandra Error - Clustering column cannot be restricted (preceding column is restricted by a non-EQ relation)Cassandra 错误 - 无法限制聚类列(前列受非 EQ 关系限制)
【发布时间】:2016-03-29 02:40:34
【问题描述】:

我们使用 Cassandra 作为我们车队管理解决方案的历史数据。我们在 Cassandra 中有一张表,其中存储了车辆的旅程细节。表结构如下所示

CREATE TABLE  journeydetails(
bucketid text,
vehicleid text,
starttime timestamp,
stoptime timestamp,
travelduration bigint,
PRIMARY KEY (bucketid,vehicleid,starttime,travelduration)
);

地点:

  1. bucketid :- 分区键,是月和年的组合
  2. vehicleid : - 车辆的唯一 ID
  3. starttime :- 旅程的开始时间
  4. endtime :- 旅程的结束时间
  5. travelduration:- 以毫秒为单位的旅行持续时间

我们要运行以下查询 - 获取车辆的所有行程 - 1234567 在 2015-12-1 和 2015-12-3 之间,其行程持续时间大于 30 分钟 p>

当我运行这个查询时:

select * from  journeydetails where bucketid in('2015-12') and vehicleid in('1234567') 
  and starttime > '2015-12-1 00:00:00' and starttime < '2015-12-3 23:59:59' 
  and travelduration > 1800000;

我得到这个结果:

InvalidRequest: code=2200 [Invalid query] message="Clustering column "travelduration"
cannot be restricted (preceding column "starttime" is restricted by a non-EQ relation)

有人对如何解决这个问题有建议吗?

【问题讨论】:

    标签: cassandra cql cql3


    【解决方案1】:
    select * from journeydetails where bucketid in('2015-12') and vehicleid in('1234567')
      and starttime > '2015-12-1 00:00:00' and starttime < '2015-12-3 23:59:59' 
      and travelduration > 1800000;
    

    那是行不通的。原因可以追溯到 Cassandra 如何在磁盘上存储数据。 Cassandra 的想法是,它在返回具有精确键的单行或从磁盘返回连续范围的行时非常有效。

    您的行由bucketid 分区,然后在磁盘上按vehicleidstarttimetravelduration 排序。因为您已经在 starttime 上执行范围查询(非 EQ 关系),所以您不能限制后面的键。这是因为travelduration 限制可能会取消范围条件中的某些行的资格。这将导致效率低下的非连续读取。 Cassandra 旨在保护您免于编写查询(例如此类),这可能具有不可预测的性能。

    这里有两种选择:

    1- 如果您可以限制 travelduration 之前的所有键列(具有等于关系),那么您可以应用大于条件:

    select * from journeydetails where bucketid='2015-12' and vehicleid='1234567'
      and starttime='2015-12-1 00:00:00' and travelduration > 1800000;
    

    当然,限制精确的starttime 可能不是非常有用。

    2- 另一种方法是完全省略 travelduration,然后您的原始查询将起作用。

    select * from journeydetails where bucketid='2015-12' and vehicleid='1234567'
      and starttime > '2015-12-1 00:00:00' and starttime < '2015-12-3 23:59:59';
    

    不幸的是,Cassandra 没有提供很大程度的查询灵活性。许多人使用Spark(与 Ca​​ssandra 一起)之类的解决方案成功地实现了这种级别的报告。

    只是一个旁注,但不要使用IN,除非你必须这样做。使用IN 查询类似于使用二级索引,因为 Cassandra 必须与多个节点通信才能满足您的查询。用单个项目调用它可能没什么大不了的。但是IN 是 RDBMS 的旧习惯之一,在深入了解 Cassandra 之前,您应该真正打破这些习惯。

    【讨论】:

    • 感谢 cmets Aron... 我将探索 Spark 作为替代方案
    【解决方案2】:

    我遇到了同样的问题。您可以简单地将索引添加到所需的列,而不是使用聚集键和主键。这样,您就可以摆脱这些陷阱,并且可以在查询中使用您想要的任何列。

    【讨论】:

      【解决方案3】:

      原来你可以在查询结束时使用“允许过滤”

      【讨论】:

      • 欢迎来到 StackOverflow。这与问题有什么关系?请提供更多详细信息。
      猜你喜欢
      • 2017-10-01
      • 2018-08-23
      • 1970-01-01
      • 1970-01-01
      • 2018-04-05
      • 1970-01-01
      • 2023-03-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多