Wednesday, 2 September 2015

Giving Cassandra 2.x Dynamic Schema

Older versions of Cassandra were Schema-less, meaning that you didn't have anywhere a definition of what a row could contain. What you need now could be partially done with a Map on Cassandra 2.1
CREATE TABLE toys (
    id text PRIMARY KEY,
    toy map<text, text>
)
Put some data ...
INSERT INTO toys (id, toy) VALUES ( '1', {'name':'Car', 'number_of_doors':'4', 'likes':'3'});
INSERT INTO toys (id, toy) VALUES ( '2', {'type':'Plane', 'flying_range':'100m'});
INSERT INTO toys (id, toy) VALUES ( '3', {'category':'Train', 'number_of_carriages':'10'});
We can now create an index on keys ...
CREATE INDEX toy_idx ON toys (KEYS(toy));
... and perform queries on Map keys ...
SELECT * FROM toys WHERE toy CONTAINS KEY 'name';
Now you can update or delete map entries like you would do with normal columns, without reading before writing
DELETE toy['name'] FROM toys WHERE id='1';
UPDATE toys set toy = toy + {'name': 'anewcar'} WHERE id = '1';
A few limitations
  1. you can not retrieve part of a collection: even if internally each entry of a map is stored as a column you can only retrieve the whole collection
  2. you have to choose whether creating an index on keys or on values, both simultaneously are not supported.
  3. since maps are typed you can't put mixed values


Reference:
http://www.datastax.com/dev/blog/does-cql-support-dynamic-columns-wide-rows
http://stackoverflow.com/questions/25098451/cql3-each-row-to-have-its-own-schema
http://docs.datastax.com/en/cql/3.1/cql/cql_reference/alter_table_r.html

No comments:

Post a Comment