如何使用in运算符更新cassandra中的数据
我有一个具有以下模式的表如何使用in运算符更新cassandra中的数据,cassandra,cassandra-2.0,cql3,Cassandra,Cassandra 2.0,Cql3,我有一个具有以下模式的表 CREATE TABLE IF NOT EXISTS group_friends( groupId timeuuid, friendId bigint, time bigint, PRIMARY KEY(groupId,friendId)); 如果组中发生任何更改(如更改组名或在表中添加新朋友等),我需要记录时间。因此,每当相关表中有任何更改时,我都需要通过groupId更新time字段的值 因为cassandra中的更新要求在where子句中提及所有主键,所以该查询
CREATE TABLE IF NOT EXISTS group_friends(
groupId timeuuid,
friendId bigint,
time bigint,
PRIMARY KEY(groupId,friendId));
如果组中发生任何更改(如更改组名或在表中添加新朋友等),我需要记录时间。因此,每当相关表中有任何更改时,我都需要通过groupId更新time字段的值
因为cassandra中的更新要求在where子句中提及所有主键,所以该查询将不会运行
update group_friends set time = 123456 where groupId = 100;
所以我可以这样做
update group_friends set time=123456 where groupId=100 and friendId in (...);
但它显示了以下错误-->
是否有任何方法可以使用集群列中的IN运算符执行更新操作?如果没有,那么可能的方法是什么
提前感谢。因为friendId是一个集群列,所以在这种情况下,批处理操作可能是一个合理且性能良好的选择,因为所有更新都将在同一个分区中进行(假设您使用相同的组id进行更新)。例如,使用java驱动程序,您可以执行以下操作:
Cluster Cluster=new Cluster.Builder().addContactPoint(“127.0.0.1”).build();
会话=cluster.connect(“朋友”);
PreparedStatement updateStmt=session.prepare(“更新组\朋友设置时间=?其中groupId=?和friendId=?”);
长时间=123456;
UUID groupId=UUIDs.startOf(0);
List friends=Lists.newArrayList(1L、2L、4L、8L、22L、1002L);
BatchStatement batch=新的BatchStatement(BatchStatement.Type.UNLOGGED);
for(Long-friendId:friends){
batch.add(updateStmt.bind(time,groupId,friendId));
}
执行(批处理);
cluster.close();
另一个优点是,由于分区密钥可以从BatchStatement推断出来,因此驱动程序将使用令牌感知路由向拥有该数据的复制副本发送请求,从而跳过网络跳
尽管这实际上是一次写入,但要注意批处理的大小。你应该注意不要把它弄得太大
在一般情况下,如果单独执行每条语句而不是使用批处理,就不会出问题。CQL传输允许在单个连接上执行多个请求,并且本质上是异步的,因此您可以一次执行多个请求,而不需要每个连接请求的典型性能成本
有关批量写入数据的更多信息,请参阅:
或者,可能有一个更简单的方法来完成你想要的。如果你真正想要完成的是维持一个群组更新时间,并且你希望群组中的所有朋友都能保持相同的更新时间,那么你可以腾出一段时间。这是Cassandra 2.0.6中的一个新特性。这样做的目的是共享groupId分区中所有行的列值。这样,您只需更新一次时间,甚至可以在用于向组中添加好友的查询中设置时间,以便将其作为一个写入操作完成
CREATE TABLE IF NOT EXISTS friends.group_friends(
groupId timeuuid,
friendId bigint,
time bigint static,
PRIMARY KEY(groupId,friendId)
);
如果您还不能使用Cassandra 2.0.6+,您可以创建一个名为group_metadata的单独表,用于维护组的时间,即:
CREATE TABLE IF NOT EXISTS friends.group_metadata(
groupId timeuuid,
time bigint,
PRIMARY KEY(groupId)
);
这里的缺点是,每当您想要获取此数据时,都需要从该表中进行选择,但这似乎是可以管理的。从2.0.6开始,静态列可用,而不是从2.1开始。谢谢,我没有意识到,我更新了我的答案。谢谢你的帮助。非常感谢。我将试用您的批处理操作的第一个解决方案。关于静态列,这是一个很好的特性。但我认为这不适合这个具体问题。我想我必须采取第三种解决办法。谢谢。
CREATE TABLE IF NOT EXISTS friends.group_metadata(
groupId timeuuid,
time bigint,
PRIMARY KEY(groupId)
);