cassandra中可变列上的Order by

cassandra中可变列上的Order by,cassandra,Cassandra,我有一个具有以下模式的表: create table xx( bucket_id int, like_count int, photo_id int, username text, PRIMARY KEY(bucket_id,like_count,photo_id) ) WITH CLUSTERING ORDER BY (like_count DESC) 在这里,我可以按相似计数的降序获取所有记录。但我需要在我的应用程序中的某个点进行更新,这是我无法做到的,因为它是主键的一部分 如果

我有一个具有以下模式的表:

create table xx(
 bucket_id int,
 like_count int,
 photo_id int,
 username text,
 PRIMARY KEY(bucket_id,like_count,photo_id)
) WITH CLUSTERING ORDER BY (like_count DESC)
在这里,我可以按相似计数的降序获取所有记录。但我需要在我的应用程序中的某个点进行更新,这是我无法做到的,因为它是主键的一部分

如果我将其从主键中删除,则无法获得基于like_计数的排序结果。在cassandra中,解决这个问题的正确方法是什么?

从主键定义中删除like_计数,并对应用程序执行排序。如果很少在几个键上发生这种更改,您可以考虑删除整个条目并用更新的值重写它,但我不推荐这种解决方案

嗯,, Carlo

从主键定义中删除like_计数,并对应用程序执行排序。如果很少在几个键上发生这种更改,您可以考虑删除整个条目并用更新的值重写它,但我不推荐这种解决方案

嗯,,
卡洛

恐怕卡桑德拉不适合处理多变的订单。考虑Reice排序集代替 话虽如此,您实际上可以使用类似CAS的语义比较和设置以及轻量级事务来实现这一点,这将使您的更新速度降低20倍左右

您还需要一个额外的表,用于查找每个bucket\u id/photo\u id的当前like\u计数

create table yy (
  bucket_id int,
  photo_id int,
  like_count int,
  PRIMARY KEY((bucket_id,photo_id))
)
然后从xx执行轻量级事务性删除,如果成功,则重新插入xx并更新到yy: 一些伪代码:

//CAS loop (supposedly in a function of args: bucket_id, photo_id, username, new_score)
for (;;) {

  //read current score (the assumption here is that the bucket_id/photo_id entry already exists in both xx and yy)
  ResultSet rs1 = select like_count from yy where bucket_id = ? and photo_id = ?
  int old_score = rs1.one().getInt(0)

  //same score don't do anything
  if (new_score == old_score) break;

  //attempt to delete using light-weight transaction (note usage of IF EXISTS)
  ResultSet r2 = delete from xx where bucket_id = ? and photo_id = ? and like_count = old_score IF EXISTS
  if (rs2.one().getBool(0)) {

    //if delete was successful, reinsert with the new score
    insert bucket_id, photo_id, photo_id, username, like_count into xx values (?, ?, ?, new_score)

    //update lookup table
    update yy set like_count = new_score where bucket_id = ? and photo_id = ?

    //we are done!
    break;
  }

  //delete was not successful, someone already updated the score
  //try again in a next CAS iteration
}

恐怕卡桑德拉不适合处理多变的订单。考虑Reice排序集代替 话虽如此,您实际上可以使用类似CAS的语义比较和设置以及轻量级事务来实现这一点,这将使您的更新速度降低20倍左右

您还需要一个额外的表,用于查找每个bucket\u id/photo\u id的当前like\u计数

create table yy (
  bucket_id int,
  photo_id int,
  like_count int,
  PRIMARY KEY((bucket_id,photo_id))
)
然后从xx执行轻量级事务性删除,如果成功,则重新插入xx并更新到yy: 一些伪代码:

//CAS loop (supposedly in a function of args: bucket_id, photo_id, username, new_score)
for (;;) {

  //read current score (the assumption here is that the bucket_id/photo_id entry already exists in both xx and yy)
  ResultSet rs1 = select like_count from yy where bucket_id = ? and photo_id = ?
  int old_score = rs1.one().getInt(0)

  //same score don't do anything
  if (new_score == old_score) break;

  //attempt to delete using light-weight transaction (note usage of IF EXISTS)
  ResultSet r2 = delete from xx where bucket_id = ? and photo_id = ? and like_count = old_score IF EXISTS
  if (rs2.one().getBool(0)) {

    //if delete was successful, reinsert with the new score
    insert bucket_id, photo_id, photo_id, username, like_count into xx values (?, ?, ?, new_score)

    //update lookup table
    update yy set like_count = new_score where bucket_id = ? and photo_id = ?

    //we are done!
    break;
  }

  //delete was not successful, someone already updated the score
  //try again in a next CAS iteration
}

该表有大约10-15k条记录,它还必须支持分页。使用您的解决方案,应用程序必须对每个页面的所有记录进行排序。很抱歉在没有评论的情况下对此进行否决,但我认为您的回答并不能给出一般性的解决方案。感谢您的解释-imho应该保留否决票,以防误导/错误的答案,但事实并非如此。如果您不认为它提供了一个通用的解决方案,请不要升级voteThe表,它有大约10-15k条记录,并且它还必须支持分页。使用您的解决方案,应用程序必须对每个页面的所有记录进行排序。很抱歉在没有评论的情况下对此进行否决,但我认为您的回答并不能给出一般性的解决方案。感谢您的解释-imho应该保留否决票,以防误导/错误的答案,但事实并非如此。如果你认为它不能提供一个普遍的解决方案,那就不要投票