【问题标题】:"Greater than" where-condition on timeuuid using Datastax C# Cassandra Driver使用 Datastax C# Cassandra 驱动程序在 timeuuid 上“大于”where-condition
【发布时间】:2014-05-13 12:05:24
【问题描述】:

如何使用 Datastax C# 驱动程序在 timeuuid 数据类型的 CQL 查询中创建“大于”或“小于”where 条件?

我在 Cassandra 中有一个表,用于存储按时间戳排序的 cookie 历史记录为 timeuuid:

CREATE TABLE cookie_history (
    cookie_id text,
    create_date timeuuid,
    item_id text,
    PRIMARY KEY ((cookie_id), create_date)
);

使用 C# 类映射表,以便使用 Datastax C# Cassandra 驱动程序进行查询:

[Table("cookie_history")]
public class CookieHistoryDataEntry
{
    [PartitionKey(1)]
    [Column("cookie_id")]
    public string CookieID;

    [ClusteringKey(1)]
    [Column("create_date")]
    public Guid CreateDate;

    [Column("item_id")]
    public string ItemID;
}

对于给定的 cookie,我想要给定时间戳之后的所有项目。

        var myTimeUuid = new Guid("5812e74d-ba49-11e3-8d27-27303e6a4831");
        var table = session.GetTable<CookieHistoryDataEntry>();
        var query = table.Where(x => x.CookieID == myCookieId
                                  && x.CreateDate > myTimeUuid);

但是这个 (x.CreateDate > myTimeUuid) 给了我一个编译时错误:

Operator '>' cannot be applied to operands of type 'System.Guid' and 'System.Guid'

【问题讨论】:

    标签: c# cassandra datastax


    【解决方案1】:

    可以在原始 CQL 中对 timeuuid 使用“大于”。因此,一种解决方案是从驱动程序执行原始 CQL:

    session.Execute(@"select * 
        from cookie_history 
        where cookie_id = 1242a96c-4bd4-8505-1bea-803784f80c18 
        and create_date > 5812e74d-ba49-11e3-8d27-27303e6a4831;");
    

    【讨论】:

      【解决方案2】:

      如果使用 CompareTo(),则可以使用 Linq:

      var query = table.Where(x => x.CookieID == myCookieId &&
                              x.CreateDate.CompareTo(myTimeUuid) > 0;
      

      Here's the code that handles the CompareTo.

      相关:如果您需要比较需要使用 Cassandra token() 方法的分区键,您可以使用 CqlToken.Create:

      var query = table.Where(x => 
          CqlToken.Create(x.PartitionKeyProperty) >= CqlToken.Create(3);
      

      【讨论】:

        【解决方案3】:

        您是否有理由尝试将您的日期表示为 Guid 而不是实际的日期类型?关于 Guid 没有大于或小于的概念,除非这是我不知道的一些极端情况。日期 A 可以大于日期 B,从我所见过的所有情况来看,Guid 的情况并非如此。

        【讨论】:

        • 我使用日期作为列键。我正在使用日期的 Guid 表示来避免列键因共同发生的事件而发生冲突。为了解决这个不支持“大于”的问题,我会在内存中查询最新的 X 条目和日期过滤器。
        • 我认为这个线程中的讨论与您的情况非常相关:stackoverflow.com/questions/5086192/…
        • 您的链接讨论的要点是,当我们还将用户特定的密钥视为标识符的一部分时,我们只会在相同的时间戳中发生一些条目冲突。但我不能这样假设,因为我的一些条目在时间戳中没有“时间部分”(而只有“日期部分”),所以我需要使用 timeuuid 来避免列键冲突。跨度>
        • guid/uuid 与 timeuuid 不同,即使它们具有相同的格式。 timeuuid 保证唯一性和排序:docs.datastax.com/en/cql/3.3/cql/cql_reference/uuid_type_r.html
        【解决方案4】:

        实际上,QueryBuilder 也可以使用,而不仅仅是原始 CQL:

        select.where(QueryBuilder.eq('cookie_id', cookie_id).  
          and(QueryBuilder.gt("create_date", 
              QueryBuilder.fcall("maxTimeuuid", 
                  QueryBuilder.fcall("unixTimestampOf", 
                      QueryBuilder.raw(timeuuid_as_string))));
        

        【讨论】:

          猜你喜欢
          • 2014-03-27
          • 1970-01-01
          • 2013-10-10
          • 2023-03-21
          • 2016-02-27
          • 2017-01-20
          • 2017-08-04
          • 2019-01-31
          • 1970-01-01
          相关资源
          最近更新 更多