Cassandra Collections
Collections allow a single column to hold multiple values. Instead of creating a separate table or joining data, you store a list of tags, a set of email addresses, or a map of key-value pairs directly inside one column. Cassandra supports three collection types: LIST, SET, and MAP.
The Shopping Bag Analogy
A regular column is like a single item you hand to a cashier — one value, one column. A collection column is like a shopping bag — one bag, multiple items inside. A LIST is a bag where the order of items matters and duplicates are allowed. A SET is a bag where every item is unique and order does not matter. A MAP is a bag of labeled envelopes — each envelope (key) contains one item (value).
Column Type Duplicates? Ordered? Example
──────────────────────────────────────────────────────────────
LIST Yes Yes ['milk','bread','milk']
SET No No {'milk','bread','eggs'}
MAP Keys unique Keys sort {'color':'red','size':'L'}
LIST
A LIST stores an ordered sequence of values. You can add items to the beginning or end, and the same value can appear more than once.
Create a Table with a LIST
CREATE TABLE playlists ( playlist_id UUID PRIMARY KEY, name TEXT, songs LIST<TEXT> );
Insert Data into a LIST
INSERT INTO playlists (playlist_id, name, songs) VALUES ( uuid(), 'Morning Drive', ['Sunrise Song', 'Road Trip Beat', 'Open Highway'] );
Add Items to a LIST
-- Append to the end: UPDATE playlists SET songs = songs + ['Afternoon Chill'] WHERE playlist_id = [uuid]; -- Prepend to the beginning: UPDATE playlists SET songs = ['Wake Up Tune'] + songs WHERE playlist_id = [uuid];
Remove an Item by Index
-- Remove the item at index 0 (first item): DELETE songs[0] FROM playlists WHERE playlist_id = [uuid];
Query a LIST Column
SELECT songs FROM playlists WHERE playlist_id = [uuid]; songs ────────────────────────────────────────────────── ['Sunrise Song', 'Road Trip Beat', 'Open Highway']
SET
A SET stores unique, unordered values. Adding the same item twice has no effect — the set simply keeps one copy. Sets work well for tags, roles, permissions, and email addresses.
Create a Table with a SET
CREATE TABLE articles ( article_id UUID PRIMARY KEY, title TEXT, tags SET<TEXT> );
Insert Data into a SET
INSERT INTO articles (article_id, title, tags)
VALUES (
uuid(),
'Cassandra for Beginners',
{'database', 'nosql', 'cassandra', 'tutorial'}
);
Add Items to a SET
UPDATE articles SET tags = tags + {'distributed'}
WHERE article_id = [uuid];
Remove an Item from a SET
UPDATE articles SET tags = tags - {'tutorial'}
WHERE article_id = [uuid];
Query a SET Column
SELECT tags FROM articles WHERE article_id = [uuid];
tags
────────────────────────────────────────────────────
{'cassandra', 'database', 'distributed', 'nosql'}
Cassandra always returns SET values in sorted order regardless of the order you inserted them.
MAP
A MAP stores key-value pairs. Each key is unique within the map and maps to one value. Maps are ideal for attributes, configuration settings, and any situation where you need a labeled value store.
Create a Table with a MAP
CREATE TABLE user_preferences ( user_id UUID PRIMARY KEY, username TEXT, settings MAP<TEXT, TEXT> );
Insert Data into a MAP
INSERT INTO user_preferences (user_id, username, settings)
VALUES (
uuid(),
'alice',
{
'theme': 'dark',
'language': 'en',
'timezone': 'UTC-5'
}
);
Add or Update a MAP Entry
-- Add a new key: UPDATE user_preferences SET settings['notifications'] = 'on' WHERE user_id = [uuid]; -- Update an existing key: UPDATE user_preferences SET settings['theme'] = 'light' WHERE user_id = [uuid];
Remove a MAP Entry
DELETE settings['notifications'] FROM user_preferences WHERE user_id = [uuid];
Query a MAP Column
SELECT settings FROM user_preferences WHERE user_id = [uuid];
settings
──────────────────────────────────────────────────────────────
{'language': 'en', 'theme': 'light', 'timezone': 'UTC-5'}
Frozen Collections
A frozen collection is serialized as a single blob instead of stored as individual cells. You cannot update individual elements of a frozen collection — you must replace the entire value. Frozen collections are required when nesting collections inside each other or using a collection as part of a primary key.
-- Frozen list — must replace the whole list to change it: CREATE TABLE archived_logs ( log_id UUID PRIMARY KEY, messages FROZEN<LIST<TEXT>> ); -- Nested collection (requires frozen): CREATE TABLE config ( config_id UUID PRIMARY KEY, data MAP<TEXT, FROZEN<LIST<TEXT>>> );
Collections in Primary Keys
You cannot use a non-frozen collection as a partition key or clustering column. Use FROZEN to make a collection eligible for use in a primary key.
When to Use Collections
Use Case Best Collection ────────────────────────────────────────────────────────────── Ordered steps or queue LIST Tags, categories, permissions SET Attributes, settings, labels MAP
Collection Size Warning
Collections stored in a single column all live within one partition cell. Very large collections (thousands of items) create performance problems. The rule of thumb is to keep collections under a few hundred items. For larger, frequently queried datasets, model the data as a separate table with a proper primary key instead.
Summary
Cassandra collections — LIST, SET, and MAP — let you store multiple values in a single column without needing a separate table. LIST preserves order and allows duplicates, SET enforces uniqueness, and MAP pairs keys with values. Use FROZEN when nesting collections or when a collection appears in a primary key. Keep collections small; large collections belong in their own table.
