Older versions of Cassandra were Schema-less, which means you didn't have a definition of what the string might contain. Now you may need partially with 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'});
Table Contents ...
id | toy ----+------------------------------------------------------- 3 | {'category': 'Train', 'number_of_carriages': '10'} 2 | {'flying_range': '100m', 'type': 'Plane'} 1 | {'likes': '3', 'name': 'Car', 'number_of_doors': '4'}
Now we can create an index on the keys ...
CREATE INDEX toy_idx ON toys (KEYS(toy));
... and execute queries on the map keys ...
SELECT * FROM toys WHERE toy CONTAINS KEY 'name'; id | toy ----+------------------------------------------------------- 1 | {'likes': '3', 'name': 'Car', 'number_of_doors': '4'}
Now you can update or delete records in the map, as if you were doing with ordinary columns without reading before writing
DELETE toy['name'] FROM toys WHERE id='1'; UPDATE toys set toy = toy + {'name': 'anewcar'} WHERE id = '1'; SELECT * FROM toys; id | toy ----+----------------------------------------------------------- 3 | {'category': 'Train', 'number_of_carriages': '10'} 2 | {'flying_range': '100m', 'type': 'Plane'} 1 | {'likes': '3', 'name': 'anewcar', 'number_of_doors': '4'}
Few limitations
- you cannot get part of the collection: even if internally each card record is stored as a column, you can only get the whole collection.
- you need to choose whether to create an index on keys or values โโare not supported at the same time.
- Since cards are being drawn, you cannot put mixed values โโ- in my examples, all integers are now strings
I personally consider the widespread use of this approach an anti-pattern.
NTN, Carlo