使用二级索引按日期进行Cassandra筛选
我需要回答以下问题: 返回每个季度最多36个月的新客户数量 列出36个月内每个季度的新客户 为了解决这个问题,我在Cassandra中创建了下表:使用二级索引按日期进行Cassandra筛选,cassandra,cql,Cassandra,Cql,我需要回答以下问题: 返回每个季度最多36个月的新客户数量 列出36个月内每个季度的新客户 为了解决这个问题,我在Cassandra中创建了下表: CREATE TABLE first_purchase_by_shopper_date ( shop_id uuid, shopper_id uuid, dt_first_purchase timestamp, ... (s
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;
末尾的if not exists(如果不存在)可确保仅在不存在条目时写入条目,例如,不会对现有记录执行更新
如何在此表中按日期进行筛选?dt_first_purchase列上的二级索引是我唯一的选择吗?这不是不可取的吗
如何在此表中按日期筛选-是
dt_first_purchase专栏是我唯一的选择——这不是不可取的吗
您当然可以尝试在dt_first_purchase上使用二级索引,并按范围查询,这也需要使用ALLOW FILTERING指令。对于性能,尤其是对于大型集群,我不建议这样做
但最重要的是,要了解Cassandra是围绕返回特定数据分区上特定键的数据而设计的。这意味着,按日期范围查询数据的最佳方法是首先使用对模型有意义的键对数据进行分区。例如,如果您有这样定义的主键:
PRIMARY KEY ((shop_id), dt_first_purchase, shopper_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)
基本上,哪个店铺id的记录记录了特定购物者购物者id的首次购买dt_first_购买
使用按店铺id划分的数据,您可以查询特定店铺id的新购物者的首次购买情况,如下所示:
PRIMARY KEY ((shop_id), dt_first_purchase, shopper_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)
此外,您还可以计算特定店铺和日期范围内新购物者的首次购买数量,如下所示:
PRIMARY KEY ((shop_id), dt_first_purchase, shopper_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的文章。他讨论了解决与您类似的用例的方法。回答得很好,感谢您花时间给出示例。