Cassandra,通过非主键进行选择

16

我是Cassandra的新手,遇到了一个问题。我创建了一个名为demodb的keyspace和一个名为users的表。这个表有3列:id(int和主键)、firstname(varchar)和name(varchar)。这个请求给了我正确的结果:

SELECT * FROM demodb.users WHERE id = 3;
但是这一个:
SELECT * FROM demodb.users WHERE firstname = 'francois';

无法工作,我收到以下错误消息:

InvalidRequest: code=2200 [Invalid query] message="No secondary indexes on the restricted columns support the provided operators: "

这个请求也不起作用:

SELECT * FROM users WHERE firstname  = 'francois'  ORDER BY id DESC LIMIT 5;
InvalidRequest: code=2200 [Invalid query] message="ORDER BY with 2ndary indexes is not supported."

提前致谢。

2个回答

17

这个请求也不起作用:

这是因为您误解了Cassandra中排序顺序的工作方式。 不要使用firstname上的二级索引,而是创建一个专门针对此查询的表,就像这样:

CREATE TABLE usersByFirstName (
  id int,
  firstname text,
  lastname text,
  PRIMARY KEY (firstname,id));

这个查询现在应该可以工作:

SELECT * FROM usersByFirstName WHERE firstname='francois'
ORDER BY id DESC LIMIT 5;

请注意,我已经在 firstnameid 上创建了一个复合主键。这将根据 firstname 对您的数据进行分区(使您能够通过它进行查询),同时也会按 id 对您的数据进行聚集。默认情况下,您的数据将按升序排列 id 进行聚类。要更改此行为,您可以在表创建语句中指定 CLUSTERING ORDER

WITH CLUSTERING ORDER BY (id DESC)

...然后您甚至不需要一个ORDER BY子句。

我最近写了一篇关于Cassandra中集群顺序工作原理的文章(我们应该有秩序)。它解释了这个问题,并涵盖了一些排序策略。


我有一个问题,我可以查询像select * from table where id = 3 and firstname = 'something'这样的语句吗?我的意思是,在提供主键的一部分时,在where子句中是否可能有非主键。 - JustTry
@JustTry 是的,只要非键列上有二级索引,就可以实现这一点。 - Aaron

10

Cassandra有一个约束条件: 任何你想在where子句中使用的字段都必须是表的主键,或者必须存在二级索引。因此,你必须创建一个firstname的索引,然后才能在where条件中使用firstname,并获得预期的结果。


对于id,您已经给出了主键,因此不需要。仅为firstname创建索引。 - Helping Hand..
1
我为firstname创建了索引,现在: SELECT * FROM demodb.users WHERE firstname = 'francois'; 可以工作,但是 ELECT * FROM users WHERE firstname = 'francois' ORDER BY id DESC LIMIT 5; 仍然无法工作。 - mel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接