Cassandra按日期过滤二级索引

时间:2014-12-16 08:57:12

标签: cassandra cql

我需要回答以下问题:

  • 每季度(最多36个月)返回新客户数
  • 每季度(最多36个月)列出新客户

我在Cassandra中创建了下表来处理这个问题:

CREATE TABLE first_purchase_by_shopper_date
(
    shop_id                     uuid,
    shopper_id                  uuid,
    dt_first_purchase           timestamp,

    ... (some text fields)

    PRIMARY KEY ((shop_id, shopper_id))
);

为了能够在Cassandra中回答此查询,我需要能够在dt_first_purchase字段中过滤此数据。

但是如果我将dt_first_purchase添加到主键,那么它会使该行对购物者来说不是唯一的 - 因此我们在表中获得了多个条目 - 但我们只想要 每个购物者一个条目。

所以我的insert语句看起来像

Insert into first first_purchase_by_shopper_date (shop_id, shopper_id, dt_first_purchase, ... ) Values(...) If Not Exists;

如果不存在,则确保仅在不存在条目时才写入条目(例如,不对现有记录执行更新。)

如何在此表上按日期过滤 - 是dt_first_purchase列上的二级索引我唯一的选择 - 这不是不受欢迎的吗?

1 个答案:

答案 0 :(得分:2)

  

如何在此表上按日期过滤 - 是一个二级索引   dt_first_purchase列是我唯一的选择 - 这不是不合适的吗?

您当然可以在dt_first_purchase上尝试二级索引(并且按范围查询也需要使用ALLOW FILTERING指令)。对于性能(特别是对于大型群集),我不建议这样做。

但首先,要了解Cassandra是围绕特定数据分区上的特定键返回数据而设计的。这意味着您按日期范围查询数据的最佳方式是首先使用对您的模型有意义的密钥对数据进行分区。例如,如果您的主键定义如下:

PRIMARY KEY ((shop_id), dt_first_purchase, shopper_id)

基本上,哪个商店(shop_id)记录了特定购物者的第一次购买(dt_first_purchase)(shopper_id)

通过商店(shop_id)对您的数据进行分区,您可以查询首次购买的新购物者以获取特定的shop_id ,如下所示:

aploetz@cqlsh:stackoverflow> SELECT * 
FROM first_purchase_by_shopper_date 
WHERE shop_id=ce1089f6-c613-4d5b-a975-5dfd677b46f9 
AND dt_first_purchase >= '2014-01-01 00:00:00' 
AND dt_first_purchase < '2014-04-01 00:00:00';

 shop_id                              | dt_first_purchase        | shopper_id                           | value
--------------------------------------+--------------------------+--------------------------------------+-------
 ce1089f6-c613-4d5b-a975-5dfd677b46f9 | 2014-02-12 18:33:22-0600 | a7480417-aaf8-42b1-85dd-5d9a4a30c204 | shopper1
 ce1089f6-c613-4d5b-a975-5dfd677b46f9 | 2014-03-13 11:33:22-0500 | 07db2b71-2dc7-421d-bf73-82a5f6c55f89 | shopper2

(2 rows)

此外,您可以计算该特定商店和日期范围的首次购物数量(新购物者),如下所示:

aploetz@cqlsh:stackoverflow> SELECT COUNT(*) FROM first_purchase_by_shopper_date
WHERE shop_id=ce1089f6-c613-4d5b-a975-5dfd677b46f9 
AND dt_first_purchase >= '2014-01-01 00:00:00' 
AND dt_first_purchase < '2014-04-01 00:00:00';

 count
-------
     2

(1 rows)

请注意,此特定示例可能不适用于您的用例。理解它是什么:演示如何在Cassandra中进行分区和查询工作。

有关更多信息,请查看Patrick McFadin关于Getting Started With Time Series Data Modeling的文章。他讨论了解决与您类似的用例的方法。