Cassandra - 如何检索最新值

时间:2015-01-27 15:45:35

标签: cassandra composite-primary-key

我在Cassandra 2.0.9中定义了下表:

CREATE TABLE history
(
    histid      uuid,
    ddate           text,       -- Day Date, i.e. 2014-11-20
    valtime         timestamp,  -- value time
    val             text,       --value
    PRIMARY KEY ((histid , ddate), valtime )
)
WITH CLUSTERING ORDER BY (valtime desc)
;

脚本每天在此表中插入数千行。

我需要能够从这张表中选择仅知道组织。 但是,我使用(histid,ddate)对行进行了分区。 意思是,我每行有一整天的历史值。

为了从这个表中选择特定的组织,我还需要提供ddate列。 例如:

SELECT * FROM history
WHERE histid= cebc4c80-daa6-11e3-bcc2-005056a975a4
AND ddate = '2014-05-16'
;

要获得最新值,我可以执行以下操作:

SELECT * FROM history
WHERE histid= cebc4c80-daa6-11e3-bcc2-005056a975a4
AND ddate = '2014-05-16'
LIMIT 1
;

但是,如果我想要任何给定组合的最新值,我无法在不知道ddate是什么的情况下提交查询,因为它是分区键的一部分。

所以......我问,最好的办法是什么?

这就是我所做的,但我不知道;不知道它是否合理:

我创建了一个辅助表:

 CREATE TABLE history_date
(
    histid          uuid,
    maxdate         timestamp, -- most recent date
    PRIMARY KEY (histid)
);

当一行插入历史表时,还会使用(histid,valtime)在该表中插入一行。

我们的程序代码可以:

1.  query the history_date table for a particular id
2. take the "maxdate" column (truncate it to yyyy-mm-dd)
3. use the histid and truncated maxdate to query the history table to retrieve the most recent value.

所以这很有效。但是,它并不是一个真正的好解决方案。

有没有更好的方法来做到这一点,也许只有一张桌子?

感谢您的时间。

3 个答案:

答案 0 :(得分:0)

好吧,正如您所提到的,您不能只知道用两个键分区的表的一个值。但是,群集订单和订单限制选项可能有所帮助,您已经使用过它们。

http://www.datastax.com/documentation/cql/3.1/cql/cql_reference/refClstrOrdr.html

https://cassandra.apache.org/doc/cql3/CQL.html#selectStmt

答案 1 :(得分:0)

您可以尝试做的一件事,就是建立一个在更宽的日期范围内分区的新表,例如your_model_name.find({}).sort('-date').exec(function(err, docs) { ... }); 。这样,您只需要知道要查询的月份即可。

month

现在,此查询应返回您要查找的内容:

CREATE TABLE history_by_month(
    histid          uuid,
    ddate           text,       -- Day Date, i.e. 2014-11-20
    valtime         timestamp,  -- value time
    val             text,       --value
    month           text,
    PRIMARY KEY (month, valtime, histid))
WITH CLUSTERING ORDER BY (valtime desc, histid asc);

唯一要记住的是,如果一个月内收到太多条目,则会遇到分区太大的机会。如果这成为问题,则可以考虑将关注范围缩小到一周。

此外,仍在使用2.0.9的任何人都应考虑升级。甚至最新的2.1补丁程序级别都更加稳定。

答案 2 :(得分:0)

我认为解决方案很简单,没有必要把事情复杂化。 只需在“histid”上制作分区键,在“ddate”上制作集群键。所以你的 DDL 应该如下所示

创建表历史 ( 组织 uuid, 日期文本, valtime 时间戳, val 文本, PRIMARY KEY ((histid) , ddate, valtime ) ) ;

您可以从以下任何组合进行查询(但请确保您的 where 子句中的顺序相同) a) 仅查询 histid b) 查询 histid 和 dddate c) 查询 histid , dddate 和 valtime

让我知道这是否适合您,或者您仍有疑问?