"Bad Request: PRIMARY KEY part to_id cannot be restricted" when trying to select using where condition

StackOverflow https://stackoverflow.com/questions/22989708

  •  01-07-2023
  •  | 
  •  

Question

Here is my cassandra table for chat kind of application:

CREATE TABLE tax_keyspace_dev.chat_messages (
  message text,
  when timestamp,
  from_id text,
  to_id text,
  read boolean,
  participants text,
  PRIMARY KEY(participants, when, to_id)
);

This query work:

select * from tax_keyspace_dev.chat_messages where participants='caone@one.com_shashank_shrivastava@acme.com' order by when;

but following queries don't work:

select * from tax_keyspace_dev.chat_messages where to_id='caone@one.com' order by when; 

Error is "Bad Request: PRIMARY KEY part to_id cannot be restricted (preceding part when is either not restricted or by a non-EQ relation)"

update tax_keyspace_dev.chat_messages set read=true where participants = 'caone@one.com_shashank_shrivastava@acme.com' and when = '2014-04-10 17:44:22+0530'; 

Error is "Bad Request: Missing mandatory PRIMARY KEY part to_id"

If I remove "to_id" from composite key and create separate index like this:

CREATE TABLE tax_keyspace_dev.chat_messages (
 message text,
 when timestamp,
 from_id text,
 to_id text,
 read boolean,
 participants text,
 PRIMARY KEY(participants, when)
);
CREATE INDEX idx_chat_messages_to ON tax_keyspace_dev.chat_messages (to_id);

then other queries work but this one fails:

select * from tax_keyspace_dev.chat_messages where to_id='caone@one.com' order by when;

with error "Bad Request: ORDER BY with 2ndary indexes is not supported."

How do I design my table so that all these use cases can work?

select * from tax_keyspace_dev.chat_messages where participants='caone@one.com_shashank_shrivastava@acme.com' order by when;
update tax_keyspace_dev.chat_messages set read=true where participants = 'caone@one.com_shashank_shrivastava@acme.com' and when = '2014-04-10 17:44:22+0530';
select * from tax_keyspace_dev.chat_messages where to_id='caone@one.com' order by when;
Was it helpful?

Solution

When using cassandra , your first part of the primary key becomes the partition key. Hence , to go to a particular partition for retrieving the row, you need to specify the primary key with equals constraint always.

select * from tax_keyspace_dev.chat_messages where participants='caone@one.com_shashank_shrivastava@acme.com' order by when;

The following query suggests that you arrive at your row partition named "participants" and then you order by when using default ordering of ASC.This order by may not be needed too as your columns are by default ordered in ascending order.

select * from tax_keyspace_dev.chat_messages where to_id='caone@one.com' order by when; 

select * from tax_keyspace_dev.chat_messages where to_id='caone@one.com' order by when;

Following query doesnt work as you are not providing the row partition to locate the value.By default, the row partition keys are used to identify the SSTables that contain the data . So, by default , cassandra doesnt support this costly operation.

What happens is simple. If you miss this row partition key, cassandra has to scan through all SSTables and get the data out of it. That can be done by using ALLOW FILTERING but your query becomes expensive as it will not be using bloom filter.

update tax_keyspace_dev.chat_messages set read=true where participants = 'caone@one.com_shashank_shrivastava@acme.com' and when = '2014-04-10 17:44:22+0530'; 

In case of updates on cassandra, its not different from inserts. Just consider a case of operating with maps. You are trying to modify a value but you dont have the complete key for the map. Internally, cassandra stores the values are "participants_when_to_id": value.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top