Cassandra WHERE Clause

The WHERE clause in CQL filters the rows that a SELECT, UPDATE, or DELETE statement targets. Cassandra's WHERE clause looks like SQL's, but it has strict rules tied to the primary key structure. Knowing those rules prevents accidental full-table scans and keeps queries fast.

WHERE and the Primary Key Rule

Cassandra requires the partition key in every WHERE clause for an efficient query. Providing the partition key tells Cassandra exactly which node holds the data so it does not have to ask every node in the cluster.

Table: orders_by_customer
PRIMARY KEY (customer_id, order_date, order_id)
              ────────────  ──────────  ────────
              Partition     Clustering  Clustering
              Key           Column 1    Column 2

Correct: Full partition key provided

SELECT * FROM orders_by_customer
WHERE customer_id = [uuid];
-- Routes to one node — fast

Incorrect: Partition key missing

SELECT * FROM orders_by_customer
WHERE order_date = '2024-05-01';
-- Requires ALLOW FILTERING — scans every node

Filtering on Clustering Columns

After you provide the partition key, you can optionally filter on clustering columns. You must follow the left-to-right rule: filter on the first clustering column before the second, and so on.

-- Valid: filter on first clustering column
SELECT * FROM orders_by_customer
WHERE customer_id = [uuid]
  AND order_date = '2024-05-01';

-- Valid: filter on both clustering columns
SELECT * FROM orders_by_customer
WHERE customer_id = [uuid]
  AND order_date   = '2024-05-01'
  AND order_id     = [order-uuid];

-- Invalid: skips order_date (first clustering column)
SELECT * FROM orders_by_customer
WHERE customer_id = [uuid]
  AND order_id = [order-uuid];
-- CQL error or requires ALLOW FILTERING

Range Operators on Clustering Columns

Clustering columns support range filters: >, <, >=, and <=. You can use ranges only on the last clustering column in the WHERE clause.

-- Orders from Q1 2024:
SELECT * FROM orders_by_customer
WHERE customer_id = [uuid]
  AND order_date >= '2024-01-01'
  AND order_date <  '2024-04-01';

-- Orders in May on a specific day:
SELECT * FROM orders_by_customer
WHERE customer_id = [uuid]
  AND order_date = '2024-05-01'
  AND order_id > [some-threshold-uuid];

IN Operator

IN lets you filter on a list of specific values. For the partition key, IN sends parallel sub-queries to each relevant node.

-- Multiple customers in one query:
SELECT * FROM customers
WHERE customer_id IN (uuid-A, uuid-B, uuid-C);

-- Multiple order dates for one customer:
SELECT * FROM orders_by_customer
WHERE customer_id = [uuid]
  AND order_date IN ('2024-01-10', '2024-03-20');

Keep IN lists short — large IN lists cause coordinator memory pressure and slower responses.

Token Function in WHERE

The token() function lets you filter by the raw token value of the partition key. This is useful for manual pagination or for splitting a full-table scan across worker processes.

-- Retrieve customers in a specific token range:
SELECT * FROM customers
WHERE token(customer_id) >= token([uuid-start])
  AND token(customer_id) <  token([uuid-end]);
Ring token range split for parallel processing:

Worker 1: token range [-9223372036854775808 to -4611686018427387904]
Worker 2: token range [-4611686018427387904 to 0]
Worker 3: token range [0                   to  4611686018427387904]
Worker 4: token range [4611686018427387904 to  9223372036854775807]

ALLOW FILTERING

ALLOW FILTERING lets you run a query that filters on a non-primary-key column. Cassandra fetches all rows that match the partition key (or scans the whole table if no partition key is provided) and then applies the filter in memory.

SELECT * FROM customers
WHERE email = 'alice@example.com'
ALLOW FILTERING;

Use ALLOW FILTERING only when the result set is guaranteed to be small — for example, during development or on a table that contains only a few hundred rows. On large tables it reads millions of rows only to discard most of them.

WHERE in UPDATE and DELETE

UPDATE and DELETE also require the full partition key in the WHERE clause. Cassandra does not allow UPDATE or DELETE without specifying which rows to target.

-- Update: must specify full primary key
UPDATE customers
SET loyalty_points = 1000
WHERE customer_id = [uuid];

-- Delete: must specify partition key at minimum
DELETE FROM orders_by_customer
WHERE customer_id = [uuid];

WHERE Clause Summary Table

Filter Type                   Allowed?  Notes
──────────────────────────────────────────────────────────────────────
Partition key equality        Yes       Most efficient; routes to one node
Partition key IN list         Yes       Parallel sub-queries per key
Clustering column equality    Yes       Must follow left-to-right order
Clustering column range       Yes       Only on last filtered cluster. col
Non-primary-key column        No*       Requires ALLOW FILTERING
Secondary index column        Yes       With caveats — see indexes topic

Summary

The WHERE clause in CQL requires the partition key for efficient, targeted queries. Clustering columns can be filtered in their defined order, and the last-filtered clustering column supports range operators. The IN operator allows querying multiple partition key values at once but should be used sparingly. Reserve ALLOW FILTERING for small, controlled datasets and use secondary indexes or redesigned tables for frequent non-key filtering.

Leave a Comment

Your email address will not be published. Required fields are marked *