在 Cassandra 上写入和更新记录以及聚类列

Write and Update record on Cassandra along with clustering columns

我有通知table和附加索引

CREATE TABLE notification (
    postid double,
    userid double,
    type text,
    message text,
    hasread boolean,
    postdate timestamp,
    PRIMARY KEY (userid, postdate)
)  WITH  CLUSTERING ORDER BY (postdate DESC);

CREATE INDEX postid ON notification(postid);

假设我插入了几行

select * from notification;

 userid | postdate                        | hasread | message                | postid | type
--------+---------------------------------+---------+------------------------+--------+---------
    104 | 2016-11-18 17:21:32.692000+0000 |   False | Let\'s do it together! |  70521 | newpost
    104 | 2016-11-18 17:21:26.511000+0000 |   False | Let\'s do it together! |  90521 | newpost
    103 | 2016-11-18 17:20:17.284000+0000 |   False | Let\'s do it together! |  40521 | newpost
    103 | 2016-11-18 17:20:02.925000+0000 |   False | Let\'s do it together! |  40521 | newpost
    103 | 2016-11-18 17:19:55.643000+0000 |   False | Let\'s do it together! |  30521 | newpost
    103 | 2016-11-18 17:19:49.029000+0000 |   False | Let\'s do it together! |  60521 | newpost

如果我做简单的查询,即

select * from notification where postid=40521;

那么结果似乎还不错

userid | postdate                        | hasread | message                | postid | type
--------+---------------------------------+---------+------------------------+--------+---------
    103 | 2016-11-18 17:20:17.284000+0000 |   False | Let\'s do it together! |  40521 | newpost
    103 | 2016-11-18 17:20:02.925000+0000 |   False | Let\'s do it together! |  40521 | newpost

或者像这样得到一行

select * from notification where postid=60521;

再一次,单行看起来不错

userid | postdate                        | hasread | message                | postid | type
--------+---------------------------------+---------+------------------------+--------+---------
    103 | 2016-11-18 17:19:49.029000+0000 |   False | Let\'s do it together! |  60521 | newpost

但是,当我在一行中更新 hasread 行时,我收到了缺少 postdate 错误,这是聚类列

update notification set hasread=true where postid=60521 and userid=103;
InvalidRequest: Error from server: code=2200 [Invalid query] message="Some clustering keys are missing: postdate"

我需要按排序顺序获取列表,这就是我必须使用 postdate 来聚类列的原因。 但是同时我需要更新特定的行。我想这与设计有关,但仍然无法弄清楚。任何建议,将不胜感激。

在 Cassandra 中更新行时,您必须提供整个主键。这基本上就是该错误消息告诉您的内容。请记住,Cassandra 不是 关系数据库,因此您将不能 能够更新 postid

此外,重要的是要记住 Cassandra 不区分插入和更新。由于特定行的唯一性由其完整的 PRIMARY KEY 决定,因此您必须为所有更新插入提供所有 PRIMARY KEY 组件。本质上,这就是您需要做的:

UPDATE notification SET hasread=true 
  WHERE userid=103 AND postdate='2016-11-18 17:19:49.029+0000';

此外,postid 似乎是一个高基数列。因此,依赖于该二级索引的调用不会执行良好。完全一样。如果您确实需要按 postid 进行查询,您应该考虑为该模式构建一个额外的查询 table。

不能通过在 where 子句中指定非主列来更新或删除。

The WHERE clause specifies the row or rows to be updated. To specify a row, the WHERE clause must provide a value for each column of the row's primary key. To specify more than one row, you can use the IN keyword to introduce a list of possible values. You can only do this for the last column of the primary key.

让我们更新 postid=60521 和 userid=103 的 hasread 首先你需要 select postdate

SELECT postdate FROM notification where postid=60521 and userid=103;

您将获得postdate。现在您可以使用 userid 和 postdate

更新 hasread 字段
update notification set hasread=true where userid=103 and postdate=?;