【问题标题】:How to query on multiple composite column prefixes with Astyanax?如何使用 Astyanax 查询多个复合列前缀?
【发布时间】:2013-10-09 15:36:28
【问题描述】:

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 并手动序列化开始和结束吗?

【问题讨论】:

    标签: java cassandra astyanax


    【解决方案1】:

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

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

    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();
    

    【讨论】:

    • 我的错;我错过了问题的一个关键部分,即我不知道开始和结束时间戳,我想得到所有这些。
    • 然后只需将 startTime 和 endTime 设置为 null。我修改了上面的代码以反映这一点。
    • 这似乎对我不起作用;我没有得到任何列。 :(
    • 很奇怪,因为我已经做过很多次了。也许我们正在使用不同版本的 Cassandra?无论如何,唯一要尝试的就是如上所示......
    • 啊哈,你看,你把它改成了我在最后一小时想出的正确解决方案:将 endTime 设置为 MAX_VALUE。 :) 如果您更新源上方的描述,我会接受。
    猜你喜欢
    • 1970-01-01
    • 2013-03-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多