我在Cassandra有一张表'评论',如下所述:
CREATE TABLE reviews (
review_id text,
downcount int,
upcount int,
creation_date timestamp,
PRIMARY KEY (review_id)
)
假设我想将upcount
值增加1,我怎样才能在Cassandra CQL中执行此操作?
当我这样做时:
UPDATE reviews SET upcount = upcount +1 WHERE review_id = '123456';
它给出了以下错误:
错误请求:非计数器列
upcount = upcount + 1
的操作无效(upcount
)。
答案 0 :(得分:20)
您可以使用Cassandra的计数器列数据类型。请记住,如果非计数器列不是复合PRIMARY KEY
的一部分,则不能将计数器列与同一列族中的非计数器列混合。所以你必须将计数器分成另一个列族,比如reviews_counts
。
CREATE TABLE reviews (
review_id text,
creation_date timestamp,
PRIMARY KEY (review_id)
)
CREATE TABLE reviews_counts (
review_id text,
downcount counter,
upcount counter,
PRIMARY KEY (review_id)
)
现在增量语句应该有效。
UPDATE keyspace.reviews_counts
SET upcount = upcount + 1
WHERE review_id = '123456'
以下是有关Cassandra计数器列的更多文档。 http://www.datastax.com/documentation/cql/3.0/cql/cql_using/use_counter_t.html
答案 1 :(得分:5)
你做不到。您必须阅读该列,更新应用程序端的值并分配更新的值。正如错误所示,只有计数器列支持cassandra中的此功能。
原因很简单。计数器跨分布式节点同步。由于cassandra确保最终的一致性,非计数器列的更新可能会在服务器端创建竞争条件。
答案 2 :(得分:0)
有点晚了,但我最终得到了一个 set<uuid>
(例如,在您的情况下,upvote 和 downvote 实体的 ID)。您可以更新类似于 counter
的集合,但不需要将其放在单独的表中。我的柜台基本上是这一套的长度。如果您没有 uuid,即使您添加和删除元素的 list<boolean>
也可能起作用。
当然,这不是一个通用的解决方案,尤其是对于比计数器低的大量数字,但也许在其他一些情况下会有所帮助。