如何根据随时间变化的状态字段为表建模以运行查询

y4ekin9u  于 2021-06-14  发布在  Cassandra
关注(0)|答案(1)|浏览(321)

目前我们有一个表,我们使用shipping\ id进行查询,将来我们需要根据状态字段current table进行查询:

CREATE TABLE shipment ( 
    shipment_id text,
    tenant_id text,
    actual_arrival_time text,
    actual_dep_time text,
    email_ids set,
    is_deleted boolean,
    modified_by text,
    modified_time timestamp,
    planned_arrival_time text,
    planned_dep_time text,
    route_id text,
    shipment_departure_date text,
    status_code text,
    PRIMARY KEY (shipment_id, tenant_id) 
); 

CREATE INDEX shipment_id_index ON shipment (tenant_id);

当前查询的
1) 选择from shipping where tenant\u id=?0 allow filtering;
2) 选择
from shipping,其中shipping\u id=?0,tenant\u id=?1;
挂起/将来的查询
从现在起给定状态代码的装运id列表3)选择*from shipping where tenant_id='y'and status_code=x;
4) 上一周给定状态代码的装运id列表
5) 延迟的装运id列表
上表可能有10-15个唯一的租户,每个表有1个发货\u id、1个租户\u id和1行,状态代码将随着发货的进行而变化,从发货\u开始、发货\u进行、发货\u延迟,发货\u延迟\u完成和发货\u完成等每个发货在其生命周期内都将经历3-5种状态,只有当给定发货\u id的状态发生更改时,才会更新当前表。
我需要创建一个新的表,它可以处理如下所示的查询
3) 到目前为止状态代码为“x”的给定租户的装运列表
4) 过去1周状态代码为“x”的给定租户的装运列表
5) 延迟装运的货物清单?

bihw5rsg

bihw5rsg1#

在cassandra中,您基于查询对表进行建模,因此实际上可以为可能执行的每个查询创建一个表。同时使用 ALLOW FILTERING 在您的查询中,应该只用于开发和测试目的,而不应用于实际的生产应用程序(请在此处检查答案:cassandra cqlengine allow filtering)。
因此,对于您提到的每个案例/问题,我建议如下: 1) SELECT * FROM shipment where tenant_id=?0 ALLOW FILTERING; 应通过下表解决这一问题:

CREATE TABLE shipment ( 
    tenant_id text,
    shipment_id text,
    actual_arrival_time text,
    actual_dep_time text,
    email_ids set,
    is_deleted boolean,
    modified_by text,
    modified_time timestamp,
    planned_arrival_time text,
    planned_dep_time text,
    route_id text,
    shipment_departure_date text,
    status_code text,
    PRIMARY KEY (tenant_id, shipment_id) 
);

在这里 tenant_idpartition key 因此,如果执行查询: SELECT * FROM shipment where tenant_id='x'; 那你就不用用了 ALLOW FILTERING 再。
更新:我还添加了 shipment_id 作为主键的一部分来处理相同的 cardinality 万一 tenant_id 不是唯一的,所以 primary key 两者兼而有之 tenant_id 以及 shipment_id 以避免用相同的 tenant_id 根据@himanshu ahire的评论。 2)SELECT * FROM shipment WHERE shipment_id='x' and tenant_id='y'; 应通过下表解决这一问题:

CREATE TABLE shipment ( 
    shipment_id text,
    tenant_id text,
    actual_arrival_time text,
    actual_dep_time text,
    email_ids set,
    is_deleted boolean,
    modified_by text,
    modified_time timestamp,
    planned_arrival_time text,
    planned_dep_time text,
    route_id text,
    shipment_departure_date text,
    status_code text,
    PRIMARY KEY ((shipment_id, tenant_id)) 
);

在这里 shipment_id 以及 tenant_id 两者都用作复合分区密钥 3) SELECT * FROM shipment WHERE tenant_id = 'y' and status_code = 'x'; 4) list of shipment id's for given status code for last 1 week 5) list of shipment id's for which got delayed 应通过下表解决这些问题:

CREATE TABLE shipment (
    status_code text,
    tenant_id text,
    shipment_id text,
    actual_arrival_time text,
    actual_dep_time text,
    email_ids set,
    is_deleted boolean,
    modified_by text,
    modified_time timestamp,
    planned_arrival_time text,
    planned_dep_time text,
    route_id text,
    shipment_departure_date text,
    PRIMARY KEY ((tenant_id, status_code), actual_arrival_time) 
) WITH CLUSTERING ORDER BY (actual_arrival_time DESC);

在这里你也应该同时使用两者 tenant_id 以及 status_code 作为 composite partition key 以及 actual_arrival_time 作为 clustering column 因此,您可以轻松创建如下查询: 3) SELECT * FROM shipment WHERE tenant_id = 'y' and status_code = 'x'; 4) SELECT * FROM shipment WHERE tenant_id = 'y' and status_code = 'x' and actual_arrival_time >= 'date of last week'; 5) SELECT * FROM shipment WHERE tenant_id = 'y' and status_code = 'x' and actual_arrival_time > planned_arrival_time; 只需对查询4做一个注解,您就可以从应用程序代码或使用cql函数发送上周的日期

相关问题