使用CQL 3.0在集合上创建自定义索引

我一直在查看CQL 3.0 数据建模文档 ,该文档描述了带有标签的列系列歌曲,如下所示:

CREATE TABLE songs ( id uuid PRIMARY KEY, title text, tags set ); 

我想获得所有具有特定标签的歌曲的列表,因此我需要添加适当的索引。

我可以很容易地在title列上创建一个索引,但是如果我尝试索引一个集合的tags列,就像这样:

 CREATE INDEX ON songs ( tags ); 

我从DataStax Java驱动程序1.0.4收到以下错误:

 Exception in thread "main" com.datastax.driver.core.exceptions.InvalidQueryException: Indexes on collections are no yet supported at com.datastax.driver.core.exceptions.InvalidQueryException.copy(InvalidQueryException.java:35) at com.datastax.driver.core.ResultSetFuture.extractCauseFromExecutionException(ResultSetFuture.java:269) 

根据JIRA问题CASSANDRA-4511 ,看起来这可以在更高版本的Cassandra(2.1)中修复。 我目前正在使用Apache Cassandra 1.2.11,但不想升级。 根据问题CASSANDRA-5615 ,在Cassandra 1.2.6中,对集合的自定义索引有支持。

问题是,唯一可用的文档指出:

Cassandra支持创建自定义索引,该索引供内部使用且超出本文档的范围。

但是,它确实建议以下语法:

 CREATE CUSTOM INDEX ON songs ( tags ) USING 'class_name'; 

在此CQL语句中指定的class_name是什么?

有没有更好的方法来索引标签,以便我可以在歌曲表中查询具有特定标签的歌曲列表?

在我看来,你尝试这样做的方式不是在Cassandra中建模的最好方法。 您可以根据查询而不是数据构建模型。 如果您需要根据标签查找歌曲,则为此创建另一个表并复制数据。 就像是 …

 CREATE TABLE tagged_songs ( tag varchar, song_id uuid, song_title varchar, ... anything else you might need with your songs here ... PRIMARY KEY ((tag), song_id) ); 

Cassandra的前提是存储便宜。 复制数据以满足您的查询。 写入速度很快,写入相同的数据3,4,10次通常很好。

您还希望将您的歌曲标题和所需的任何其他信息存储到此表中。 你不想抓住大量的ID,并在阅读时尝试加入。 这不是关系数据库。

当有人标记歌曲时,您可能希望将标记插入到集合中,并将其添加到tagged_songs表中。 查询标签X的所有歌曲基本上是O(1)。