Cassandra SUM(Map <text,int>) is it possible? - cassandra

In Casssandra is it possible to sum of int values in a
My DB structure is attr Map<text,int> is it possible to use
select sum (attr['salary']) from testtable or something equivalent

Cassandra not support Map, List and Set in the Select,Insert with [] ( Ex: attr['salary'] )
You can use User Defined Data Type.
Example:
Define your user defined data type like as below
mytype {
salary (int)
}
create 'attr' field with type 'mytype'
now you can do query like as below
select sum(attr.salary) from yourtable.

User-Defined Aggregate Function (UDA)

Related

Convert single UDT object to list of UDT in Cassandra table

I have two userdefined type in Cassandra. First one is using the second object as frozen object inside it.
CREATE TYPE my_keyspace.test (
testid text,
testdate text,
testdata frozen<testdata>
);
CREATE TYPE my_keyspace.testdata (
subject text,
metadata text
);
Now my requirement is to convert this single object to list of UDT . Something like this
CREATE TYPE my_keyspace.test (
testid text,
testdate text,
testdata list<frozen<testdata>>
);
Is it possible to update single object to list of object in Cassandra. Whata are options available to update the schema.
The only way to do it, is to add another field with required type using the ALTER TYPE, and start to use this new field, migrating existing data using some code. Cassandra doesn't allow to change type of the existing fields, and you can't also drop a field from UDT. So your type should be something like this:
CREATE TYPE my_keyspace.test (
testid text,
testdate text,
testdata frozen<testdata>
testdata_lst list<frozen<testdata>>
);
Existing data could be migrated into a list, and then set to null to free the space.

What is the query for Altering a Cassandra UDT TYPE to add multiple attributes

I have a Cassandra UDT column that has about 10 attributes and now we are planning to add 3 more attributes to it. What is the query to add all the three attributes. I can add them one by one by executing 3 different queries like alter TYPE commentmetadata ADD columnname1 <type>;, alter TYPE commentmetadata ADD columnname2 <type>;, alter TYPE commentmetadata ADD columnname3 <type>;.
Can this is be done in a single query? Datastax documentation mentions that it can be done by something like this ALTER TYPE commentmetadata ADD (field_name cql_datatype[,...]) add fields by entering a field name followed by the data type in a comma separated list.
I tried the following 3 queries but I am getting query error for all.
ALTER TYPE commentmetadata ADD columnname1 int, columnname2 int, columnname3 int;
ALTER TYPE commentmetadata ADD [columnname1 int, columnname2 int, columnname3 int];
ALTER TYPE commentmetadata ADD (columnname1 int, columnname2 int, columnname3 int);
According to CQL grammar, this is not possible:
/**
* ALTER TYPE <name> ALTER <field> TYPE <newtype>;
* ALTER TYPE <name> ADD <field> <newtype>;
* ALTER TYPE <name> RENAME <field> TO <newtype> AND ...;
*/
alterTypeStatement returns [AlterTypeStatement.Raw stmt]
: K_ALTER K_TYPE name=userTypeName { $stmt = new AlterTypeStatement.Raw(name); }
(
K_ALTER f=fident K_TYPE v=comparatorType { $stmt.alter(f, v); }
| K_ADD f=fident v=comparatorType { $stmt.add(f, v); }
| K_RENAME f1=fident K_TO toF1=fident { $stmt.rename(f1, toF1); }
( K_AND fn=fident K_TO toFn=fident { $stmt.rename(fn, toFn); } )*
)
;
You can file a JIRA for Cassandra to add such functionality.
P.S. Can you point to page where it's written in the DataStax docs?

How to convert a cassandra column value to a corresponding enum while querying

We have a cassandra column of type int, this value of int corresponds to value of a enum, is there a way to convert this int column to enum string while querying.
It's not possible to make in the CQL itself, but Java driver supports corresponding functionality by using the EnumOrdinalCodec class (example from documentation):
enum State {INIT, RUNNING, STOPPING, STOPPED}
cluster.getConfiguration().getCodecRegistry()
.register(new EnumOrdinalCodec<State>(State.class));
// schema: create table ordinal_example(id int PRIMARY KEY, state int)
session.execute("insert into ordinal_example (id, state) values (1, ?)", State.INIT);

UPDATE prepared statement with Object

I have an Object that maps column names to values. The columns to be updated are not known beforehand and are decided at run-time.
e.g. map = {col1: "value1", col2: "value2"}.
I want to execute an UPDATE query, updating a table with those columns to the corresponding values. Can I do the following? If not, is there an elegant way of doing it without building the query manually?
db.none('UPDATE mytable SET $1 WHERE id = 99', map)
is there an elegant way of doing it without building the query manually?
Yes, there is, by using the helpers for SQL generation.
You can pre-declare a static object like this:
const cs = new pgp.helpers.ColumnSet(['col1', 'col2'], {table: 'mytable'});
And then use it like this, via helpers.update:
const sql = pgp.helpers.update(data, cs) + /* WHERE clause with the condition */;
// and then execute it:
db.none(sql).then(data => {}).catch(error => {})
This approach will work with both a single object and an array of objects, and you will just append the update condition accordingly.
See also: PostgreSQL multi-row updates in Node.js
What if the column names are not known beforehand?
For that see: Dynamic named parameters in pg-promise, and note that a proper answer would depend on how you intend to cast types of such columns.
Something like this :
map = {col1: "value1", col2: "value2",id:"existingId"}.
db.none("UPDATE mytable SET col1=${col1}, col2=${col2} where id=${id}", map)

How to sort by sum of field of a relation on sails.js?

I searched a lot about sorting elements by sum of votes (in another model), like I do in SQL here :
SELECT item.* FROM item
LEFT JOIN (
SELECT
vote.item,
SUM(vote.value) AS vote.rating
FROM vote
GROUP BY vote.item
) AS res ON item.id = vote.item
ORDER BY res.rating DESC
Is there a way to do it via waterline methods ?
I think you can't do the left join with simple waterline methods, but you can use the .query method to execute your raw SQL syntax.
Sails MySQL adapter makes sum('field') conflict with sort('field'). It will generate SQL query like:
SELECT SUM(table.field) AS field FROM table ORDER BY table.field;
But I want:
SELECT SUM(table.field) AS field FROM table ORDER BY field;
It same as:
SELECT SUM(table.field) AS f FROM table ORDER BY f;
My solution is using lodash.sortBy() to process results. https://lodash.com/docs/4.16.4#sortBy

Resources