如何使用Astyanax查询多个复合列前缀?

时间:2013-10-09 15:36:29

标签: java cassandra astyanax

Astyanax通过其AnnotatedCompositeSerializer支持Cassandra中的复合列。我有一个具有3字段复合列名称的列族,类似于此示例,改编自Astyanax's documentation(列实际上不是sessionIdtoken,假装它们是出于参数的缘故):

// Annotated composite class
public class SessionEvent {
  @Component(ordinal=0) UUID sessionId;
  @Component(ordinal=1) UUID token;
  @Component(ordinal=2) UUID timestamp;

  public SessionEvent() { }
}

static AnnotatedCompositeSerializer<SessionEvent> eventSerializer
      = new AnnotatedCompositeSerializer<>(SessionEvent.class);
static ColumnFamily<String, SessionEvent> CF_SESSION_EVENTS
      = new ColumnFamily<>("SessionEvents",
                           StringSerializer.get(), eventSerializer);

// Querying cassandra for a column slice on one prefix, but we want two!
OperationResult<ColumnList<SessionEvent>> result = keyspace.prepareQuery(CF_SESSION_EVENTS)
    .getKey("UserId1")
    .withColumnRange(eventSerializer.buildRange()
        .withPrefix("SessionId1")
        .build())
    .execute();

问题是:我想在前缀中查询包含两个复合列(在本例中为sessionIdtoken)的所有列,而不仅仅是一个,并且对于所有时间戳,不是只是在一个范围内。使用CQL3显然可以轻松实现这一点,但是我坚持使用Cassandra 1.0.x并且无法找到Astyanax接受的方式(通过调用withPrefix(UUID)两次或传递复合数据结构)

Astyanax有没有办法做到这一点?我可以以某种方式使用基本RangeBuilder并手动序列化开始和结束吗?

1 个答案:

答案 0 :(得分:1)

Cassandra中的列按顺序存储。在您的示例中,sessionId是最重要的,后跟令牌,timestamp是最不重要的。换句话说,列按sessionId排序,然后是令牌,然后是时间戳。

如果我理解正确,您正在尝试使用指定的sessionId以及令牌和任何时间查询列。由于上述原因,具有匹配的sessionId和令牌的列将连续存储。您可以通过以下方式使用最小/最大日期来查询任何日期:

startTime = new Date(0);
endTime = new Date(Long.MAX_VALUE);

SessionEvent from = new SessionEvent(sessionId, token, startTime);
SessionEvent to = new SessionEvent(sessionId, token, endTime);

RangeBuilder rb = new RangeBuilder().setStart(from).setEnd(to);

OperationResult<ColumnList<SessionEvent>> result = keyspace
        .prepareQuery(CF_SESSION_EVENTS)
        .getKey("UserId1")
        .withColumnRange(rb.build())
        .execute();