Frozen keyword in cassandra - cassandra

No matter if i use or do not use frozen keyword with UDT, it is updating records.
I have table user:
CREATE TABLE demokeyspace.user (
userid text PRIMARY KEY,
address1 frozen<address>,
password text,
uname text
)
and address type:
CREATE TYPE demokeyspace.address (
street text,
city text,
zip_code int
);
It is updating street:'updated street' and city and zip_code to null
As per Cassandra, it does not allow update of UDT values if it is declared as FROZEN.
can somebody help me on this ?

If you use not-frozen UDT, and want to update one field, then you can use following (see docs):
update user set address1.street='updated street' where userid='2';
In your case, you're updating the full address1 field with UDT that has only one value inside...
In case if you're using frozen UDT, you must to specify all values during update, something like you're doing right now, but providing all values.
Use of frozen values is encouraged if you're always updating the full record, but if you'll need to update parts of the record, you shouldn't use it.

Related

Cassandra - Nodejs - Issue while retrieving list type values

for example below is the table structure.
CREATE TABLE table_name(
name text,
id text PRIMARY KEY,
details list<text>
)
Assume
details[0]-> contact number,
details[1]-> Address
I want to write a query to extract contact number from this table.
Actually, you should not store arrays of data. The best and simplest way will be to refactor your database to something like this.
CREATE TABLE table_name(
name text,
id text PRIMARY KEY,
contact number NOT NULL,
address text NOT NULL,
)
Then you could do SELECT contact FROM table_name. If the same address can be reused between multiple entities then you may think about adding one more table Addresses and then using foreign keys to relate this data.

Cassandra UDT TYPE remove a field name

I have a UDT type in Cassandra. I want to ALTER this type to remove the country field. I don't find any delete or remove field for ALTER TYPE documentation. https://docs.datastax.com/en/cql/3.3/cql/cql_reference/cqlAlterType.html
create type bank_payment (
account_number text,
name text,
city text,
country text,
key text
);
Please help sharing ALTER command to remove one field from above UDT.
Cassandra UDT doesn't store any actual data and its the table where this UDT referred to has actual data. So go ahead and drop the UDT & recreate it with the correct definition that you want. Remember the serialization of old sstables that had this UDT (with additional column) will be different from the new one.
So if possible add a new version name to this UDT as you recreate, say
bank_payment_v2

Cassandra Update query | timestamp column as clustering key

I have a table in cassandra with following schema:
CREATE TABLE user_album_entity (
userId text,
albumId text,
updateDateTimestamp timestamp,
albumName text,
description text,
PRIMARY KEY ((userId), updateDateTimestamp)
);
The query required to get data would have a where userId = xxx order by updateTimestamp. Hence the schema had updateDateTimestamp.
Problem comes in updating the column of table.The query is: Update the album information for user where user id = xxx. But as per specs,for update query I would need the exact value of updateDateTimestamp which in normal world scenario, an application would never send.
What should be the answer to such problems since I believe this a very common use case where select query requires ordering on timestamp. Any help is much appreciated.
The problem is that your table structure allows the same album to have multiple records with the only difference being the timestamp (the clustering key).
Three possible solutions:
Remove the clustering key and sort your data at application level.
Remove the clustering key and add a Secondary Index to the timestamp field.
Remove the clustering key and create a Materialized View to perform the query.
If your usecase is such that each partition will contain exactly one row,
then you can model your table like:
CREATE TABLE user_album_entity (
userId text,
albumId text static,
updateDateTimestamp timestamp,
albumName text static,
description text static,
PRIMARY KEY ((userId), updateDateTimestamp)
);
modelling the table this way enables Update query to be done in following way:
UPDATE user_album_entity SET albumId = 'updatedAlbumId' WHERE userId = 'xyz'
Hope this helps.

What is the Difference between tuple and user defined type in Cassandra

Can someone tell me the difference between tuple and user defined types in Cassandra
Datastax documents that
You can use a tuple as an alternative to a user-defined type when you
don't need to add new fields.
User-defined types gives you more flexibility with altering the number of fields in case you need to update the data later on, as well as allowing you to give meaningful names to each field. The classic example of how UDTs work is an address.
CREATE TYPE mykeyspace.address (
street_number int,
street text,
city text,
zip_code int,
phones set<text>
);
and creating the table
CREATE TABLE users (
id uuid PRIMARY KEY,
address frozen <address>
);
The tuple equivalent would be
CREATE TABLE users (
id uuid PRIMARY KEY,
address <tuple<int, text, text, int, set<text>>
);
So tuples would be best for a fixed amount of collected data where field names aren't important (an address column is definitely not a good use case; fields matter--street_number and zip_code could potentially be confused--and you wouldn't be able to add detailed fields later on). UDT would allow this, and also let you query by field name.
Furthermore, there is no significant difference in performance.

Text based selection of records using CQL

I have a text field like 'address' in my Cassandra table. I want to search records on the basis of some piece of text from the 'address' field like city or street name.
for Example: I have address like 'House No. 18, Shehzad Colony, M.D.A. Chowk Lahore'. Here I want to search records having a part of string 'M.D.A. Chowk Lahore' in the address field.
how can i do this using CQL shell. can anyone guide me...
thanks...
There really isn't a way to do this out-of-the-box. In Cassandra, you need to design your tables to fit your query patterns. So if searching for addresses by city (or whatever) is a pattern you need to support, then there are a couple of ways to do this.
You can create a new query table, and partition by city:
CREATE TABLE userAddressesByCity (
userID uuid,
firstName text,
lastName text,
street text,
city text,
province text,
postalCode text,
PRIMARY KEY (city,userID));
This table structure would support querying by city as a partition key, and it also has userID as a clustering key to ensure uniqueness.
If you're working with addresses, a useful technique is to create a User Defined Type (UDT). UDTs are useful if you want to store a user's address in a single column. But you would still want to create a table specifically-designed to serve a query by whichever column you require.
Note: You could try one table and create a secondary index on one of the columns, but secondary indexes perform poorly at-scale, so I don't recommend that.

Resources