Unable to delete data from a Cassandra CF - cassandra

So I have a CF whose Schema looks something like this :
CREATE TABLE "emp" (
id text,
column1 text,
column2 text,
PRIMARY KEY (id, column1, column2)
)
I have an entry which looks like this and I want to delete it :
20aff8144049 | name | someValue
So i tried this command :
Delete column2 from emp where id='20aff8144049';
It failed with below error:
no viable alternative at input '20aff8144049' (...column2 from emp where id=["20aff8144049]...)
Can someone help with where I'm going wrong? Thanks!

You can't delete or set null to primary key column
You have to delete the entire row.

You only can delete an entry using a valid value for your primary key. You defined your primary key to include (id, column1, column2) which means that you have to put all the corresponding values in your where clause.
However, I assume you wanted to be able to delete by id only. Therefore, I'd suggest you re-define your column family like this:
CREATE TABLE "emp" (
id text,
column1 text,
column2 text,
PRIMARY KEY ((id), column1, column2)
)
where id is your partition key and column1 and column2 are your clustering columns.

Related

Cassandra add column after particular column

I need to alter the table to add a new column after a particular column or as last column, I have been through the document but no luck.
Let's say I'm starting with a table that has this definition:
CREATE TABLE mykeyspace.letterstable (
column_n TEXT,
column_b TEXT,
column_c TEXT,
column_z TEXT,
PRIMARY KEY (column_n));
1- Adding a column is a simple matter.
ALTER TABLE mykeyspace.letterstable ADD column_j TEXT;
2- After adding the new column, my table definition will look like this:
desc table mykeyspace.letterstable;
CREATE TABLE mykeyspace.letterstable (
column_n TEXT,
column_b TEXT,
column_c TEXT,
column_j TEXT,
column_z TEXT,
PRIMARY KEY (column_n));
This is because columns in Cassandra are stored by ASCII-betical order, after the keys (so column_n will always be first, because it is the only key). I can't tell Cassandra that I want my new column_j to go after column_z. It's going to put it between column_c and column_z on its own.
Cassandra will store table data based on partition & clustering key.
Standard CQL for adding column:
ALTER TABLE keyspace.table ADD COLUMN column1 columnType;
Running DESC table for a given table via CQLSH does not portray how the data is stored. It will always list the partition key & clustering key first; then the remaining columns in alphabetical order.
https://docs.datastax.com/en/cql/3.1/cql/cql_reference/alter_table_r.html
Cassandra create table won't keep column order

CQL IN set query

Have a table
REATE TABLE IF NOT EXISTS tabletest (uuid text, uuidHotel text, uuidRoom text, uuidGuest text, bookedTimeStampSet set<text>, PRIMARY KEY (uuidHotel, uuidRoom));
Tried to select with IN:
select * from tabletest where uuidhotel = 'uuidHotel' and bookedtimestampset IN ('1460710800000');
Got
'bookedtimestampset' (set<text>) cannot be restricted by a 'IN' relation"
Can I select elements by IN Set filter?
Can I select elements by IN Set filter?
No, but you can put a secondary index on bookedtimestampset and use the CONTAINS operator:
aploetz#cqlsh:stackoverflow> CREATE INDEX timeset_idx ON tabletest(bookedtimestampset);
aploetz#cqlsh:stackoverflow> SELECT uuidhotel,uuidroom FROM tabletest
WHERE uuidhotel = 'uuidHotel1' and bookedtimestampset CONTAINS '1460710800000';
uuidhotel | uuidroom
------------+----------
uuidHotel1 | uuidroom1
(1 rows)
Normally I wouldn't recommend a secondary index, but as long as you are filtering by a partition key (uuidhotel) it should perform ok.
Can I select elements by IN Set filter?
you can't use clause IN with your primary key. It is highly important to understand how significantly data model influences on query performance. Of course, you can add secondary index for column bookedtimestampset but in this case be ready to for performance degradation.
CREATE TABLE IF NOT EXISTS tabletest (uuid text, uuidHotel text, uuidRoom text, uuidGuest text, bookedTimeStampSet set, PRIMARY KEY (uuidHotel, uuidRoom));
your compound primary key consists of one partition key uuidHotel and one clustering key uuidRoom which means that all your hotels and rooms would physically stored on same node in order as result retrieval of rows is very efficient. bookedTimeStampSet is different column which would be spread through whole cluster and it is just impossible to restrict by this column without secondary indexing one.
Consequently. I would recommend you to create primary key according to your future queries even if you need to duplicate some data which is common practice for NoSql database such Cassandra is.
e.q.
CREATE TABLE IF NOT EXISTS tabletest (uuid text, uuidHotel text,
uuidRoom text, uuidGuest text, bookedTimeStamp timestamp, PRIMARY KEY
(uuidHotel, bookedTimeStamp , uuidRoom))
it allows you to make a query like
select * from tabletest where uuidhotel = 'uuidHotel' and
bookedtimestamp > '1460710800000 and bookedtimestamp < '1460710900000'

How to list all unique components of a composite partition key - Cassandra

Given a table with a composite partition key like:
CREATE TABLE testtable (
column1 text,
column2 text,
column3 text,
column4 text,
column5 text,
column6 text,
PRIMARY KEY ((column1, column2, column3, column4))
)
How could I get all the unique values of only one partition column? Now, I know this doesn't work:
SELECT DISTINCT column2 from testtable;
However, I can do
SELECT DISTINCT column1, column2, column3, column4 from testtable;
So, is there a way (within CQL because the result of that query might be quite large) to query that query result like you would do in SQL? Something like this:
SELECT DISTINCT column2 FROM (SELECT DISTINCT column1, column2, column3, column4 from testtable);
Which doesn't work. Or do I really have to use Python (or other alternatives) for this?
Simply put, there is no way to achieve this in CQL. The entirety of the partitioning key defines which Cassandra node is responsible for handling the data, and queries on it. Therefore, it always has to be given in its entirety.

Columns ordering in Cassandra

When I create a table in CQL, is it necessary to be exact for the order of column that are NOT in the primary_key and NOT clustering columns :
CREATE TABLE user (
a ascii,
b ascii,
c ascii,
PRIMARY KEY (a)
);
Is it equivalent to ?
CREATE TABLE user (
a ascii,
c ascii, <-- switched
b ascii, <-- switched
PRIMARY KEY (a)
);
Thank you for your help
Both of those statements will fail, because of:
The extra comma.
You have not provided a primary key definition.
Assuming you had those fixed, then the answer is still "yes they are the same."
Cassandra applies its own order to your columns at table creation time. Consider this table as I have typed it:
CREATE TABLE testorder (
acolumn text,
jcolumn text,
dcolumn text,
bcolumn text,
apkey text,
bpkey text,
ackey text,
bckey text,
PRIMARY KEY ((bpkey,apkey),bckey,ackey));
After creating it, I'll describe the table so you can see the order that Cassandra has applied to the columns.
aploetz#cqlsh:stackoverflow> desc table testorder ;
CREATE TABLE stackoverflow.testorder (
bpkey text,
apkey text,
bckey text,
ackey text,
acolumn text,
bcolumn text,
dcolumn text,
jcolumn text,
PRIMARY KEY ((bpkey, apkey), bckey, ackey)
) WITH CLUSTERING ORDER BY (bckey ASC, ackey ASC)
Essentially, Cassandra will order the partition keys and the clustering keys (ordered by their precedence in the PRIMARY KEY definition), and then the columns follow in ascending order.

Set/Query columns form secondary compound key with CQL3

Say I have the following CF with compound Primary Key
CREATE TABLE dpt (
empID int,
deptID int,
PRIMARY KEY (deptID, empID));
Because of the compound PK, cassandra will create one row for each dept, and the employee IDs that are members of the department will be stored as columns on that row with the :empID as the column name.
Quesiton #1: can I set a value to that column (e.g the employ name) with CQL3? if so, how?
Question #2: can I see the value of <individual_employ_ID>:empID column - if exists - with CQL3?
thanks
Question #1:
CREATE TABLE dpt (
empID int,
deptID int,
empName text,
PRIMARY KEY (deptID, empID));
Question #2:
Please take a look at the examples:
http://www.datastax.com/docs/1.1/references/cql/INSERT
http://www.datastax.com/docs/1.1/references/cql/UPDATE

Resources