根据Where子句更新Cassandra中的列

时间:2014-04-18 03:54:39

标签: cassandra cql cql3

我有一个非常简单的表

cqlsh:hell> describe columnfamily info ;

CREATE TABLE info (
  nos int,
  value map<text, text>,
  PRIMARY KEY (nos)
) 

以下是我尝试更新值的查询。

update info set value = {'count' : '0' , 'onget' :  'function onget(value,count) { count++ ; return {"value": value, "count":count} ; }' } where nos  <= 1000 ;
Bad Request: Invalid operator LTE for PRIMARY KEY part nos

我使用任何运算符来指定约束。它抱怨说操作员无效。我不确定我在这里做错了什么,根据cassandra 3.0 cql doc,有类似的更新查询。

以下是我的版本

[cqlsh 4.1.0 | Cassandra 2.0.3 | CQL spec 3.1.1 | Thrift protocol 19.38.0]

我不知道,哪里出错了。

3 个答案:

答案 0 :(得分:7)

答案实际上在我的评论中,但需要一些细节。重申评论...

where子句的第一个谓词必须唯一地标识分区键。在您的情况下,由于主键只有一列,分区键==主键。

Cassandra无法对分区进行范围扫描。在CQL语言中,分区是一个潜在的宽存储行,由密钥唯一标识。在这种情况下,您的nos列中的值。分区键的值被散列到标记中,这些标记明确标识数据在集群中的位置。由于该哈希没有命令,因此Cassandra不能使用除了相等之外的任何运算符来将语句路由到正确的目的地。这不是可能被更新的主键索引,它是Cassandra中的基本分区机制。因此,您不能使用不等式运算符作为谓词的第一个子句。您可以在后续子句中使用它们,因为已经识别了分区,现在您正在处理一组有序的列。

答案 1 :(得分:3)

您不能在分区键上使用不相等的条件(nos是您的分区键)。

http://cassandra.apache.org/doc/cql3/CQL.html#selectWhere

答案 2 :(得分:-1)

Cassandra目前不支持查询中的用户定义函数,如下所示。

update info set value = {'count' : '0' , 'onget' :  'function onget(value,count) { count++ ; return {"value": value, "count":count} ; }' } where nos  <= 1000 ;

首先,您可以将此onget函数推送到应用程序层吗?您可以先查询nos&lt;的所有行。 1000.然后通过一些批量查询递增那些行。

否则,您可以使用nos的计数器列,而不是int数据类型。但请注意,除非非计数器列是复合键的一部分,否则不能将map数据类型与计数器列族混合使用。

此外,您可能不希望拥有nos,这是一个将值更改为主键的列。

CREATE TABLE info (
  id UUID,
  value map<text, text>,
  PRIMARY KEY (id)
) 

CREATE TABLE nos_counter (
  info_id UUID,
  nos COUNTER,
  PRIMARY KEY (info_id)
) 

现在您可以像这样更新nos计数器。

update info set nos = nos + 1 where info_id = 'SOME_UUID';