Not getting exact output using User defined data types in cassandra - cassandra

In CASSANDRA, I created a User defined data type,
cqlsh:test> create type fullname ( firstname text, lastname text );
And i created a table with that data type and inserted into the table like this,
cqlsh:test> create table people ( id UUID primary key, names set < frozen <fullname>> );
cqlsh:test> insert into people (id, names) values (
... now(),
... {{firstname: 'Jim', lastname: 'Jones'}}
... );
When i querying into the table iam getting output with some additional values like this
cqlsh:test> SELECT * from people ;
id | names
--------------------------------------+--------------------------------------------
3a59e2e0-14df-11e5-8999-abcdb7df22fc | {\x00\x00\x00\x03Jim\x00\x00\x00\x05Jones}
How can i get output like this???
select * from people;
id | names
--------------------------------------+-----------------------------------------
69ba9d60-a06b-11e4-9923-0fa29ba414fb | {{firstname: 'Jim', lastname: 'Jones'}}

Related

Get value from specific map-key in Cassandra

For example. I have a map under the column 'users' in a table called 'table' with primary key 'Id'.
If the map looks like this, {{'Phone': '1234567899'}, {'City': 'Dublin'}}, I want to get the value from key 'Phone' for specific 'Id', in Cassandra database.
Yes, that's possible to do with CQL when using a MAP collection.
To test this, I created a simple table using the specifications and data you mentioned above:
> CREATE TABLE stackoverflow.usermap (
id text PRIMARY KEY,
users map<text, text>);
> INSERT INTO usermap (id,users)
VALUES ('1a',{'Phone': '1234567899','City': 'Dublin'});
> SELECT * FROM usermap WHERE id='1a';
id | users
----+-------------------------------------------
1a | {'City': 'Dublin', 'Phone': '1234567899'}
(1 rows)
Then, I queried with the same WHERE clause, but altering my SELECT to pull back the user's phone only:
> SELECT users['Phone'] FROM usermap WHERE id='1a';
users['Phone']
----------------
1234567899
(1 rows)

How to update and replace in Cassandra a UDT field value?

Does Cassandra support update of a UDT field value? something like replacing it with a new value?
I have user_fav_payment_method UDT and I need to replace cash with debit card:
update user_ratings set
user_fav_payment_method{'cash'} = {'debit cards'}
where rating_id = 66;
This code is wrong but I need to do something similar to this, how can i do it?
Per documentation:
In Cassandra 3.6 and later, user-defined types that include only non-collection fields can update individual field values. Update an individual field in user-defined type data using the UPDATE command. The desired key-value pair are defined in the command. In order to update, the UDT must be defined in the CREATE TABLE command as an unfrozen data type.
You can use . notation to update only individual fields of the non-frozen UDT, like this:
cqlsh> use test;
cqlsh:test> create type payment_method ( method text, data text);
cqlsh:test> create table users (id int primary key, pay_method payment_method);
cqlsh:test> insert into users (id, pay_method) values (1, {method: 'cash', data: 'usd'});
cqlsh:test> select * from users;
id | pay_method
----+-------------------------------
1 | {method: 'cash', data: 'usd'}
(1 rows)
cqlsh:test> update users set pay_method.method = 'card' where id = 1;
cqlsh:test> select * from users;
id | pay_method
----+-------------------------------
1 | {method: 'card', data: 'usd'}
(1 rows)

cassandra data consistency issue

Hi I'm new in Apache Cassandra and I found article about Basic Rules of Cassandra Data Modeling. In example 1 are created 2 tables
CREATE TABLE users_by_username (
username text PRIMARY KEY,
email text,
age int
)
CREATE TABLE users_by_email (
email text PRIMARY KEY,
username text,
age int
)
This tables contains same data (username, email and age). Here I don't understand how to insert data into two tables. I think, that I have to execute two separate inserts. One for table users_by_username and one for table users_by_email. But how to maintain data consistency between tables. For example when I insert data into first table and I forgot to insert data to second table ... or the other way
It's your job as developer to make sure that data is in sync. Although, you can use things like materialized views to generate another "table" with slightly different primary key (there are some rules on what could be changed). For your case, for example, you can have following:
CREATE TABLE users_by_username (username text PRIMARY KEY,
email text, age int);
create MATERIALIZED VIEW users_by_email as SELECT * from
users_by_username where email is not null and
username is not null primary key (email, username);
and if you insert data as
insert into users_by_username (username, email, age)
values ('test', 'test#domain.com', 30);
you can query the materialized view for data in addition to query by username
SELECT * from users_by_username where username = 'test' ;
username | age | email
----------+-----+-----------------
test | 30 | test#domain.com
SELECT * from users_by_email where email = 'test#domain.com';
email | username | age
-----------------+----------+-----
test#domain.com | test | 30

Cassandra & Solr Join 2 Cores

I've 2 models for Cassandra with the same partition key:
CREATE TABLE users(
parent_id int,
user_id text,
PRIMARY KEY ((parent_id), user_id )
);
CREATE TABLE user_actions(
parent_id int,
user_id text,
type text,
created_at int,
data map<text, text>,
PRIMARY KEY((parent_id), user_id, created_at)
);
I want to find all the users how made an action and belong to the same parent_id.
Right now I'm getting all the users, even if they did not made an action, I'm using it like this:
http://ADDRESS/solr/name.users/select?q=parent_id:1&fq={!join+fromIndex=name.user_actions}type:click
Thanks!
There are not 'from' and 'to' parameters to tell solr on which fields it should make the join, so your filter query should be something like:
fq={!join from=user_id fromIndex=name.user_actions to=user_id force=true}type:click

cql-import dynamic map Entries in cassandra

I have 2 mysql tables as given below
Table Employee:
id int,
name varchar
Table Emails
emp_id int,
email_add varchar
Table Emails & Employee are connected by employee.id = emails.emp_id
I have entries like:
mysql> select * from employee;
id name
1 a
2 b
3 c
mysql> select * from emails;
empd_id emails
1 aa#gmail.com
1 aaa#gmail.com
1 aaaa#gmail.com
2 bb#gmail.com
2 bbb#gmail.com
3 cc#gmail.com
6 rows in set (0.02 sec)
Now i want to import data to cassandra in below 2 formats
---format 1---
table in cassandra : emp_details:
id , name , email map{text,text}
i.e. data should be like
1 , a, { 'email_1' : 'aa#gmail.com' , 'email_2 : 'aaa#gmail.com' ,'email_3' :'aaaa#gmail.com'}
2 , b , {'email_1' :'bb#gmail.com' ,'email_2':'bbb#gmail.com'}
3, c, {'email_1' : 'cc#gmail.com'}
---- format 2 ----
i want to have the dynamic columns like
id , name, email_1 , email_2 , email_3 .... email_n
Please help me for the same. My main concern is to import data from mysql into above 2 formats.
Edit: change list to map
Logically, you don't expect an user to have >1000 emails, I would suggest to use Map<text, text> or even List<text>. It's a good fit for CQL collections.
CREATE TABLE users (
id int,
name text,
emails map<text,text>,
PRIMARY KEY(id)
);
INSERT INTO users(id,name,emails)
VALUES(1, 'a', {'email_1': 'aa#gmail.com', 'email_2': 'bb#gmail.com', 'email_3': 'cc#gmail.com'});

Resources