2

我的数据模型:-

tid                                  | codes        | raw          | type
-------------------------------------+--------------+--------------+------
a64fdd60-1bc4-11e5-9b30-3dca08b6a366 | {12, 34, 53} | {sdafb=safd} |  cmd

CREATE TABLE MyTable (
tid       TIMEUUID,
type      TEXT,
codes     SET<INT>,
raw       TEXT,
PRIMARY KEY (tid)
);
CREATE INDEX ON myTable (codes);

如何根据多个设置值查询表以返回行。

这有效: -

select * from logData where codes contains 34;

但我想根据多个设定值获取行,但这些都不起作用:-

select * from logData where codes contains 34, 12; or 
select * from logData where codes contains 34 and 12; or
select * from logData where codes contains {34, 12};

请协助。

4

4 回答 4

7

如果我创建您的表结构并在上面插入与您类似的行,我可以检查codes集合中的多个值,如下所示:

aploetz@cqlsh:stackoverflow2> SELECT * FROM mytable 
    WHERE codes CONTAINS 34 
      AND codes CONTAINS 12
      ALLOW FILTERING;

 tid                                  | codes        | raw          | type
--------------------------------------+--------------+--------------+------
 2569f270-1c06-11e5-92f0-21b264d4c94d | {12, 34, 53} | {sdafb=safd} |  cmd

(1 rows)

现在正如其他人所提到的,让我告诉你为什么这是一个糟糕的主意......

使用集合上的二级索引(并且基数似乎相当高)每个节点都必须针对每个查询进行检查。Cassandra 的想法是尽可能频繁地按分区键查询,这样每次查询只需访问一个节点。Apple 的 Richard Low 写了一篇很棒的文章,名为The sweet spot for Cassandra 二级索引。它应该让您重新思考使用二级索引的方式。

其次,我能让 Cassandra 接受这个查询的唯一方法是使用ALLOW FILTERING。这意味着,Cassandra 可以应用所有过滤条件(WHERE 子句)的唯一方法是拉回每一行并单独过滤掉不符合条件的行。效率极低。需要明确的是,ALLOW FILTERING 指令是您永远不应该使用的。

在任何情况下,如果codes您需要查询某些东西,那么您应该设计一个额外的查询表,codes并将其作为 PRIMARY KEY 的一部分。

于 2015-06-26T13:49:25.323 回答
3

您使用的数据模型效率极低。集合旨在用于获取给定主键的一组数据,而不是相反。如果这是需要的,您将不得不重新考虑模型本身。

我建议为您在集合中使用的每个值创建不同的列,然后将这些列用作复合主键。

于 2015-06-26T07:30:30.427 回答
3

您是否真的希望仅根据代码获取所有日志条目?那可能是一个相当大的数据集。实际上,您不会查看特定日期/日期范围吗?我会重点关注,然后使用代码进行过滤,甚至完全在客户端过滤代码。

如果您有很多代码,并且您在集合上进行索引,则可能会导致索引的基数非常高,这会导致您出现问题。无论您有自己的查找表,还是使用索引,请记住,您基本上有一个“表”,其中 pk 是值,并且与该值匹配的每个“行”都有该值的行。如果它看起来大到无法接受,那么它就是这样。

我建议重新审视这个要求 - 再次......你真的需要与某个代码组合匹配的所有日志条目吗?

如果您确实需要分析全部内容,那么我建议您使用 Spark 来运行该作业。然后您可以运行 Spark 作业,每个节点将处理同一节点上的数据;与完全在应用程序中进行全表处理相比,这将显着降低影响。

于 2015-06-26T09:40:18.730 回答
2

我知道已经晚了。IMO 模型几乎没有细微的变化就足以达到预期的效果。可以做的是拥有与被查询集合的幂集成员一样多的行。

CREATE TABLE data_points_ks.mytable (
    codes frozen<set<int>>,
    tid timeuuid,
    raw text,
    type text,
    PRIMARY KEY (codes, tid)
) WITH CLUSTERING ORDER BY (tid ASC)

INSERT INTO mytable (tid, codes, raw, type) VALUES (now(), {}, '{sdafb=safd}', 'cmd');
INSERT INTO mytable (tid, codes, raw, type) VALUES (now(), {12}, '{sdafb=safd}', 'cmd');
INSERT INTO mytable (tid, codes, raw, type) VALUES (now(), {34}, '{sdafb=safd}', 'cmd');
INSERT INTO mytable (tid, codes, raw, type) VALUES (now(), {12, 34}, '{sdafb=safd}', 'cmd');
INSERT INTO mytable (tid, codes, raw, type) VALUES (now(), {53}, '{sdafb=safd}', 'cmd');
INSERT INTO mytable (tid, codes, raw, type) VALUES (now(), {12, 53}, '{sdafb=safd}', 'cmd');
INSERT INTO mytable (tid, codes, raw, type) VALUES (now(), {34, 53}, '{sdafb=safd}', 'cmd');
INSERT INTO mytable (tid, codes, raw, type) VALUES (now(), {12, 34, 53}, '{sdafb=safd}', 'cmd');

 tid                                  | codes        | raw          | type
--------------------------------------+--------------+--------------+------
 8ae81763-1142-11e8-846c-cd9226c29754 |     {34, 53} | {sdafb=safd} |  cmd
 8746adb3-1142-11e8-846c-cd9226c29754 |     {12, 53} | {sdafb=safd} |  cmd
 fea77062-1142-11e8-846c-cd9226c29754 |         {34} | {sdafb=safd} |  cmd
 70ebb790-1142-11e8-846c-cd9226c29754 |     {12, 34} | {sdafb=safd} |  cmd
 6c39c843-1142-11e8-846c-cd9226c29754 |         {12} | {sdafb=safd} |  cmd
 65a954f3-1142-11e8-846c-cd9226c29754 |         null | {sdafb=safd} |  cmd
 03c60433-1143-11e8-846c-cd9226c29754 |         {53} | {sdafb=safd} |  cmd
 82f68d70-1142-11e8-846c-cd9226c29754 | {12, 34, 53} | {sdafb=safd} |  cmd

那么下面的查询就足够了,不需要任何过滤。

SELECT * FROM mytable 
WHERE codes = {12, 34};

或者

SELECT * FROM mytable 
WHERE codes = {34};
于 2018-02-14T06:01:45.317 回答