非二级索引查询尚不支持非主键列(事件类型)上的 Cassandra 谓词

问题描述 投票:0回答:2

我开发了一个如下所示的表,主键为id,是uuid类型

 id                                   | date                     | eventtype    | log      | password | priority | sessionid | sourceip     | user       | useragent
--------------------------------------+--------------------------+--------------+----------+----------+----------+-----------+--------------+------------+------------
 6b47e9b0-d11a-11e8-883c-5153f134200b |                     null | LoginSuccess |  demolog |     1234 |       10 |    Demo_1 | 123.12.11.11 |       Aqib |  demoagent
 819a58d0-cd3f-11e8-883c-5153f134200b |                     null | LoginSuccess |  demolog |     1234 |       10 |    Demo_1 | 123.12.11.11 |       Aqib |  demoagent
 f4fae220-d133-11e8-883c-5153f134200b | 2018-10-01 04:01:00+0000 | LoginSuccess |  demolog |     1234 |       10 |    Demo_1 | 123.12.11.11 |       Aqib |  demoagent

但是当我尝试查询如下所示的内容时

select * from loginevents where eventtype='LoginSuccess';

我收到如下错误

InvalidRequest: Error from server: code=2200 [Invalid query] message="Predicates on non-primary-key columns (eventtype) are not yet supported for non secondary index queries"

这是我的桌子

cqlsh:events> describe loginevents;

CREATE TABLE events.loginevents (
    id uuid PRIMARY KEY,
    date timestamp,
    eventtype text,
    log text,
    password text,
    priority int,
    sessionid text,
    sourceip text,
    user text,
    useragent text
) WITH bloom_filter_fp_chance = 0.01
    AND caching = '{"keys":"ALL", "rows_per_partition":"NONE"}'
    AND comment = ''
    AND compaction = {'class': 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy'}
    AND compression = {'sstable_compression': 'org.apache.cassandra.io.compress.LZ4Compressor'}
    AND dclocal_read_repair_chance = 0.1
    AND default_time_to_live = 0
    AND gc_grace_seconds = 864000
    AND max_index_interval = 2048
    AND memtable_flush_period_in_ms = 0
    AND min_index_interval = 128
    AND read_repair_chance = 0.0
    AND speculative_retry = '99.0PERCENTILE';

我该如何解决这个问题

cassandra database-indexes secondary-indexes
2个回答
4
投票

您问题的直接答案是在

eventtype
列上创建二级索引,如下所示:

CREATE INDEX my_index ON events.loginevents (eventtype);

然后您可以过滤此特定列:

SELECT * FROM loginevents WHERE eventtype='LoginSuccess';

但是,此解决方案可能会严重影响集群的性能。

如果您来自 SQL 世界并且对 Cassandra 不熟悉,请阅读有关 cassandra 建模的介绍,例如这个

首先要识别查询,然后根据查询创建表。

在Cassandra中,数据根据分区键分布在集群中,因此读取属于同一分区的记录非常快。

就您而言,也许一个好的开始是根据

eventtype
:

对您的记录进行分组
CREATE TABLE events.loginevents (
  id uuid,
  date timestamp,
  eventtype text,
  log text,
  password text,
  priority int,
  sessionid text,
  sourceip text,
  user text,
  useragent text,
  PRIMARY KEY (eventtype, id)

然后你可以像这样选择:

SELECT * FROM loginevents WHERE eventtype='LoginSuccess';

甚至:

SELECT * FROM loginevents WHERE eventtype in ('LoginSuccess', 'LoginFailure');

(这不是一个完美的模型,在生产之前肯定需要改进。)


2
投票

在 Cassandra 中,只能查询 PRIMARY 键和部分聚类列,不可能查询所有字段。 如果你想查询“eventtype”,你应该在 Apache Solr 的表或索引表定义中使用二级索引,并使用 Solr 进行查询。如下所示:

CREATE INDEX loginevents_type
   ON events.loginevents (eventtype);
© www.soinside.com 2019 - 2024. All rights reserved.