Cassandra获取IN子句中包含的每个元素的最新条目

时间:2017-04-15 19:13:47

标签: cassandra cql

所以,我有一个Cassandra CQL语句,如下所示:

SELECT * FROM DATA WHERE APPLICATION_ID = ? AND PARTNER_ID = ? AND LOCATION_ID = ? AND DEVICE_ID = ? AND DATA_SCHEMA = ?

此表按时间戳列排序。

该功能由REST API提供,并且可以指定一个过滤器参数来获取最新的行,然后我将“LIMIT 1”附加到CQL语句的末尾,因为它按时间戳排序列按降序排列。我想要做的是允许他们指定多个设备ID来获取最新的条目。所以,我的问题是,有没有办法在Cassandra做这样的事情:

SELECT * FROM DATA WHERE APPLICATION_ID = ? AND PARTNER_ID = ? AND LOCATION_ID = ? AND DEVICE_ID IN ? AND DATA_SCHEMA = ?

仍然使用类似“LIMIT 1”的内容来仅返回每个设备ID的最新行?或者,我是否只需为每个设备执行单独的CQL语句以获取每个设备的最新行?

FWIW,表的复合键如下所示:

PRIMARY KEY ((application_id, partner_id, location_id, device_id, data_schema), activity_timestamp)
) WITH CLUSTERING ORDER BY (activity_timestamp DESC);

2 个答案:

答案 0 :(得分:1)

  

当有很多参数时,不建议使用IN,并且无论如何它都要求多个分区,并且它会给协调器节点施加压力。

并非你无法做到。这是完全合法的,但大多数时候它没有表现,也没有建议。如果你为整个声明指定限制,基本上你不能从分区中选择第一个项目。最简单的选择是向群集发出多个查询(IN中的每个元素都将成为一个查询)并将limit 1添加到每个查询中。

说实话,这是我在很多项目中的解决方案,它的工作非常好。基本上协调器无论如何都要进入多个节点,但是还需要为你提供更多的工作来获取所有请求,可能会遇到超时等问题。

  

简而言之,如果客户端多次询问(使用多个协调员的请求较少),而不是让单个协调员对所有工作都这样做,那么群集会更好,性能更高。

如果您无法为群集提供更多磁盘空间,这就是全部

通常的Cassandra解决方案

建议cassandra中的数据准备好进行查询(首先查询)。所以基本上你必须有一个额外的表,它具有与你现在相同的分区键,你必须删除聚类列activity_timestamp。即。

PRIMARY KEY ((application_id, partner_id, location_id, device_id, data_schema))

double (())是故意的。

每次你写入你的表时,你也会将数据写入latest_entry(没有activity_timestamp的表)然后你可以指定你需要的查询,这个表包含最新的条目因此,您不必使用限制1,因为每个分区键只有一个条目...这将是cassandra中的常用解决方案。

如果您害怕额外的写入,请不要担心,它们价格便宜且受到cpu约束。随着卡桑德拉,它始终"带来写作"我想:)

基本上它取决于你:

  1. 多个查询 - 一点重构,无需额外的空间费用
  2. 新架构 - 写入时的其他插入,额外的空间成本

答案 1 :(得分:1)

您的表定义不适合IN子句的此类使用。实际上,它在主键的最后一个字段或聚类键的最后一个字段上受支持。所以你可以:

  • 交换主键的最后两个字段
  • 对每个设备ID使用一个查询