Creating a custom index on a collection using CQL 3.0

有些话、适合烂在心里 提交于 2019-12-07 22:26:08

问题


I have been looking at the CQL 3.0 data modelling documentation which describes a column family of songs with tags, created like this:

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

I would like to get a list of all songs which have a specific tag, so I need to add an appropriate index.

I can create an index on the title column easily enough, but if I try to index the tags column which is a collection, like this:

CREATE INDEX ON songs ( tags );

I get the following error from the DataStax Java driver 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)

It looks like this may be fixed in a later version of Cassandra (2.1) according to JIRA issue CASSANDRA-4511. I am currently using Apache Cassandra 1.2.11 however, and do not want to upgrade yet. According to issue CASSANDRA-5615 though, in Cassandra 1.2.6 there is support for custom indexes on collections.

The problem is, the only documentation available states:

Cassandra supports creating a custom index, which is for internal use and beyond the scope of this document.

But, it does suggest the following syntax:

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

What is the class_name that is specified in this CQL statement?

Is there a better way of indexing the tags so that I can query the songs table for a list of songs that have a specific tag?


回答1:


The way you are trying to do this isn't the best way to model it within Cassandra in my view. You build models based on your queries, not your data. If you need to find songs based by tag, then you make another table for that and duplicate the data. Something like ...

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)
);

The premise in Cassandra is that storage is cheap. Duplicate your data to meet your queries. Writes are fast, and writing the same data 3,4,10 times is normally fine.

You also want to store your song title and any other info you need into this table. You don't want to grab a load of IDs and try join on it when reading. This isn't a relational DB.

When someone tags a song, you might want to insert the tag into the set as you have it as present, AND add it to the tagged_songs table too. Querying for all songs with tag X is then basically O(1).



来源:https://stackoverflow.com/questions/20434036/creating-a-custom-index-on-a-collection-using-cql-3-0

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!