You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@cassandra.apache.org by Matope Ono <ma...@gmail.com> on 2014/05/16 06:23:07 UTC

Query first 1 columns for each partitioning keys in CQL?

Hi, I'm modeling some queries in CQL3.

I'd like to query first 1 columns for each partitioning keys in CQL3.

For example:

create table posts(
> author ascii,
> created_at timeuuid,
> entry text,
> primary key(author,created_at)
> );
> insert into posts(author,created_at,entry) values
> ('john',minTimeuuid('2013-02-02 10:00+0000'),'This is an old entry by
> john');
> insert into posts(author,created_at,entry) values
> ('john',minTimeuuid('2013-03-03 10:00+0000'),'This is a new entry by john');
> insert into posts(author,created_at,entry) values
> ('mike',minTimeuuid('2013-02-02 10:00+0000'),'This is an old entry by
> mike');
> insert into posts(author,created_at,entry) values
> ('mike',minTimeuuid('2013-03-03 10:00+0000'),'This is a new entry by mike');


And I want results like below.

mike,1c4d9000-83e9-11e2-8080-808080808080,This is a new entry by mike
> john,1c4d9000-83e9-11e2-8080-808080808080,This is a new entry by john


I think that this is what "SELECT FIRST " statements did in CQL2.

The only way I came across in CQL3 is "retrieve whole records and drop
manually",
but it's obviously not efficient.

Could you please tell me more straightforward way in CQL3?

Re: Query first 1 columns for each partitioning keys in CQL?

Posted by Matope Ono <ma...@gmail.com>.
Hmm. Something like a user-managed-index looks the only way to do what I
want to do.
Thank you, I'll try that.


2014-05-17 18:07 GMT+09:00 DuyHai Doan <do...@gmail.com>:

> Clearly with your current data model, having X latest post for each author
> is not possible.
>
>  However, what's about this ?
>
> CREATE TABLE latest_posts_per_user (
>    author ascii
>    latest_post map<uuid,text>,
>    PRIMARY KEY (author)
> )
>
>  The latest_post will keep a collection of X latest posts for each user.
> Now the challenge is to "update" this latest_post map every time an user
> create a new post. This can be done in a single CQL3 statement: UPDATE
> latest_posts_per_user SET latest_post = latest_post + {new_uuid: 'new
> entry', oldest_uuid: null} WHERE author = xxx;
>
>  You'll need to know the uuid of the oldest post to remove it from the map
>
>
>
> On Sat, May 17, 2014 at 8:53 AM, 後藤 泰陽 <ma...@gmail.com> wrote:
>
>> Hello,
>>
>> Thank you for your addressing.
>>
>> But I consider LIMIT to be a keyword to limits result numbers from WHOLE
>> results retrieved by the SELECT statement.
>> The result with SELECT.. LIMIT is below. Unfortunately, This is not what
>> I wanted.
>> I wante latest posts of each authors. (Now I doubt if CQL3 can't
>> represent it)
>>
>> cqlsh:blog_test> create table posts(
>>              ... author ascii,
>>              ... created_at timeuuid,
>>              ... entry text,
>>              ... primary key(author,created_at)
>>              ... )WITH CLUSTERING ORDER BY (created_at DESC);
>> cqlsh:blog_test>
>> cqlsh:blog_test> insert into posts(author,created_at,entry) values
>> ('john',minTimeuuid('2013-02-02 10:00+0000'),'This is an old entry by
>> john');
>> cqlsh:blog_test> insert into posts(author,created_at,entry) values
>> ('john',minTimeuuid('2013-03-03 10:00+0000'),'This is a new entry by
>> john');
>> cqlsh:blog_test> insert into posts(author,created_at,entry) values
>> ('mike',minTimeuuid('2013-02-02 10:00+0000'),'This is an old entry by
>> mike');
>> cqlsh:blog_test> insert into posts(author,created_at,entry) values
>> ('mike',minTimeuuid('2013-03-03 10:00+0000'),'This is a new entry by
>> mike');
>> cqlsh:blog_test> select * from posts limit 2;
>>
>>  author | created_at                           | entry
>>
>> --------+--------------------------------------+------------------------------
>>    mike | 1c4d9000-83e9-11e2-8080-808080808080 |  This is a new entry by
>> mike
>>    mike | 4e52d000-6d1f-11e2-8080-808080808080 | This is an old entry by
>> mike
>>
>>
>>
>>
>> 2014/05/16 23:54、Jonathan Lacefield <jl...@datastax.com> のメール:
>>
>> Hello,
>>
>>  Have you looked at using the CLUSTERING ORDER BY and LIMIT features of
>> CQL3?
>>
>>  These may help you achieve your goals.
>>
>>
>> http://www.datastax.com/documentation/cql/3.1/cql/cql_reference/refClstrOrdr.html
>>
>> http://www.datastax.com/documentation/cql/3.1/cql/cql_reference/select_r.html
>>
>> Jonathan Lacefield
>> Solutions Architect, DataStax
>> (404) 822 3487
>> <http://www.linkedin.com/in/jlacefield>
>>
>> <http://www.datastax.com/cassandrasummit14>
>>
>>
>>
>> On Fri, May 16, 2014 at 12:23 AM, Matope Ono <ma...@gmail.com>wrote:
>>
>>> Hi, I'm modeling some queries in CQL3.
>>>
>>> I'd like to query first 1 columns for each partitioning keys in CQL3.
>>>
>>> For example:
>>>
>>> create table posts(
>>>> author ascii,
>>>> created_at timeuuid,
>>>> entry text,
>>>> primary key(author,created_at)
>>>> );
>>>> insert into posts(author,created_at,entry) values
>>>> ('john',minTimeuuid('2013-02-02 10:00+0000'),'This is an old entry by
>>>> john');
>>>> insert into posts(author,created_at,entry) values
>>>> ('john',minTimeuuid('2013-03-03 10:00+0000'),'This is a new entry by john');
>>>> insert into posts(author,created_at,entry) values
>>>> ('mike',minTimeuuid('2013-02-02 10:00+0000'),'This is an old entry by
>>>> mike');
>>>> insert into posts(author,created_at,entry) values
>>>> ('mike',minTimeuuid('2013-03-03 10:00+0000'),'This is a new entry by mike');
>>>
>>>
>>> And I want results like below.
>>>
>>> mike,1c4d9000-83e9-11e2-8080-808080808080,This is a new entry by mike
>>>> john,1c4d9000-83e9-11e2-8080-808080808080,This is a new entry by john
>>>
>>>
>>> I think that this is what "SELECT FIRST " statements did in CQL2.
>>>
>>> The only way I came across in CQL3 is "retrieve whole records and drop
>>> manually",
>>> but it's obviously not efficient.
>>>
>>> Could you please tell me more straightforward way in CQL3?
>>>
>>
>>
>>
>

Re: Query first 1 columns for each partitioning keys in CQL?

Posted by DuyHai Doan <do...@gmail.com>.
Clearly with your current data model, having X latest post for each author
is not possible.

 However, what's about this ?

CREATE TABLE latest_posts_per_user (
   author ascii
   latest_post map<uuid,text>,
   PRIMARY KEY (author)
)

 The latest_post will keep a collection of X latest posts for each user.
Now the challenge is to "update" this latest_post map every time an user
create a new post. This can be done in a single CQL3 statement: UPDATE
latest_posts_per_user SET latest_post = latest_post + {new_uuid: 'new
entry', oldest_uuid: null} WHERE author = xxx;

 You'll need to know the uuid of the oldest post to remove it from the map



On Sat, May 17, 2014 at 8:53 AM, 後藤 泰陽 <ma...@gmail.com> wrote:

> Hello,
>
> Thank you for your addressing.
>
> But I consider LIMIT to be a keyword to limits result numbers from WHOLE
> results retrieved by the SELECT statement.
> The result with SELECT.. LIMIT is below. Unfortunately, This is not what I
> wanted.
> I wante latest posts of each authors. (Now I doubt if CQL3 can't represent
> it)
>
> cqlsh:blog_test> create table posts(
>              ... author ascii,
>              ... created_at timeuuid,
>              ... entry text,
>              ... primary key(author,created_at)
>              ... )WITH CLUSTERING ORDER BY (created_at DESC);
> cqlsh:blog_test>
> cqlsh:blog_test> insert into posts(author,created_at,entry) values
> ('john',minTimeuuid('2013-02-02 10:00+0000'),'This is an old entry by
> john');
> cqlsh:blog_test> insert into posts(author,created_at,entry) values
> ('john',minTimeuuid('2013-03-03 10:00+0000'),'This is a new entry by
> john');
> cqlsh:blog_test> insert into posts(author,created_at,entry) values
> ('mike',minTimeuuid('2013-02-02 10:00+0000'),'This is an old entry by
> mike');
> cqlsh:blog_test> insert into posts(author,created_at,entry) values
> ('mike',minTimeuuid('2013-03-03 10:00+0000'),'This is a new entry by
> mike');
> cqlsh:blog_test> select * from posts limit 2;
>
>  author | created_at                           | entry
>
> --------+--------------------------------------+------------------------------
>    mike | 1c4d9000-83e9-11e2-8080-808080808080 |  This is a new entry by
> mike
>    mike | 4e52d000-6d1f-11e2-8080-808080808080 | This is an old entry by
> mike
>
>
>
>
> 2014/05/16 23:54、Jonathan Lacefield <jl...@datastax.com> のメール:
>
> Hello,
>
>  Have you looked at using the CLUSTERING ORDER BY and LIMIT features of
> CQL3?
>
>  These may help you achieve your goals.
>
>
> http://www.datastax.com/documentation/cql/3.1/cql/cql_reference/refClstrOrdr.html
>
> http://www.datastax.com/documentation/cql/3.1/cql/cql_reference/select_r.html
>
> Jonathan Lacefield
> Solutions Architect, DataStax
> (404) 822 3487
> <http://www.linkedin.com/in/jlacefield>
>
> <http://www.datastax.com/cassandrasummit14>
>
>
>
> On Fri, May 16, 2014 at 12:23 AM, Matope Ono <ma...@gmail.com> wrote:
>
>> Hi, I'm modeling some queries in CQL3.
>>
>> I'd like to query first 1 columns for each partitioning keys in CQL3.
>>
>> For example:
>>
>> create table posts(
>>> author ascii,
>>> created_at timeuuid,
>>> entry text,
>>> primary key(author,created_at)
>>> );
>>> insert into posts(author,created_at,entry) values
>>> ('john',minTimeuuid('2013-02-02 10:00+0000'),'This is an old entry by
>>> john');
>>> insert into posts(author,created_at,entry) values
>>> ('john',minTimeuuid('2013-03-03 10:00+0000'),'This is a new entry by john');
>>> insert into posts(author,created_at,entry) values
>>> ('mike',minTimeuuid('2013-02-02 10:00+0000'),'This is an old entry by
>>> mike');
>>> insert into posts(author,created_at,entry) values
>>> ('mike',minTimeuuid('2013-03-03 10:00+0000'),'This is a new entry by mike');
>>
>>
>> And I want results like below.
>>
>> mike,1c4d9000-83e9-11e2-8080-808080808080,This is a new entry by mike
>>> john,1c4d9000-83e9-11e2-8080-808080808080,This is a new entry by john
>>
>>
>> I think that this is what "SELECT FIRST " statements did in CQL2.
>>
>> The only way I came across in CQL3 is "retrieve whole records and drop
>> manually",
>> but it's obviously not efficient.
>>
>> Could you please tell me more straightforward way in CQL3?
>>
>
>
>

Re: Query first 1 columns for each partitioning keys in CQL?

Posted by Bryan Talbot <br...@playnext.com>.
I think there are several issues in your schema and queries.

First, the schema can't efficiently return the single newest post for every
author. It can efficiently return the newest N posts for a particular
author.

On Fri, May 16, 2014 at 11:53 PM, 後藤 泰陽 <ma...@gmail.com> wrote:

>
> But I consider LIMIT to be a keyword to limits result numbers from WHOLE
> results retrieved by the SELECT statement.
>


This is happening due to the incorrect use of minTimeuuid() function. All
of your created_at values are equal so you're essentially getting 2 (order
not defined) values that have the lowest created_at value.

The minTimeuuid() function is mean to be used in the WHERE clause of a
SELECT statement often with maxTimeuuid() to do BETWEEN sort of queries on
timeuuid values.




> The result with SELECT.. LIMIT is below. Unfortunately, This is not what I
> wanted.
> I wante latest posts of each authors. (Now I doubt if CQL3 can't represent
> it)
>
> cqlsh:blog_test> create table posts(
>              ... author ascii,
>              ... created_at timeuuid,
>              ... entry text,
>              ... primary key(author,created_at)
>              ... )WITH CLUSTERING ORDER BY (created_at DESC);
> cqlsh:blog_test>
> cqlsh:blog_test> insert into posts(author,created_at,entry) values
> ('john',minTimeuuid('2013-02-02 10:00+0000'),'This is an old entry by
> john');
> cqlsh:blog_test> insert into posts(author,created_at,entry) values
> ('john',minTimeuuid('2013-03-03 10:00+0000'),'This is a new entry by
> john');
> cqlsh:blog_test> insert into posts(author,created_at,entry) values
> ('mike',minTimeuuid('2013-02-02 10:00+0000'),'This is an old entry by
> mike');
> cqlsh:blog_test> insert into posts(author,created_at,entry) values
> ('mike',minTimeuuid('2013-03-03 10:00+0000'),'This is a new entry by
> mike');
> cqlsh:blog_test> select * from posts limit 2;
>
>  author | created_at                           | entry
>
> --------+--------------------------------------+------------------------------
>    mike | 1c4d9000-83e9-11e2-8080-808080808080 |  This is a new entry by
> mike
>    mike | 4e52d000-6d1f-11e2-8080-808080808080 | This is an old entry by
> mike
>
>
>
>


To get most recent posts by a particular author, you'll need statements
more like this:

cqlsh:test> insert into posts(author,created_at,entry) values
('john',now(),'This is an old entry by john'); cqlsh:test> insert into
posts(author,created_at,entry) values ('john',now(),'This is a new entry by
john'); cqlsh:test> insert into posts(author,created_at,entry) values
('mike',now(),'This is an old entry by mike'); cqlsh:test> insert into
posts(author,created_at,entry) values ('mike',now(),'This is a new entry by
mike');

and then you can get posts by 'john' ordered by newest to oldest as:

cqlsh:test> select author, created_at, dateOf(created_at), entry from posts
where author = 'john' limit 2 ;

 author | created_at                           | dateOf(created_at)       |
entry
--------+--------------------------------------+--------------------------+------------------------------
   john | 7cb1ac30-df85-11e3-bb46-4d2d68f17aa6 | 2014-05-19 11:43:36-0700 |
 This is a new entry by john
   john | 74bb6750-df85-11e3-bb46-4d2d68f17aa6 | 2014-05-19 11:43:23-0700 |
This is an old entry by john


-Bryan

Re: Query first 1 columns for each partitioning keys in CQL?

Posted by 後藤 泰陽 <ma...@gmail.com>.
Hello,

Thank you for your addressing.

But I consider LIMIT to be a keyword to limits result numbers from WHOLE results retrieved by the SELECT statement.
The result with SELECT.. LIMIT is below. Unfortunately, This is not what I wanted.
I wante latest posts of each authors. (Now I doubt if CQL3 can't represent it)

> cqlsh:blog_test> create table posts(
>              ... author ascii,
>              ... created_at timeuuid,
>              ... entry text,
>              ... primary key(author,created_at)
>              ... )WITH CLUSTERING ORDER BY (created_at DESC);
> cqlsh:blog_test> 
> cqlsh:blog_test> insert into posts(author,created_at,entry) values ('john',minTimeuuid('2013-02-02 10:00+0000'),'This is an old entry by john');
> cqlsh:blog_test> insert into posts(author,created_at,entry) values ('john',minTimeuuid('2013-03-03 10:00+0000'),'This is a new entry by john');
> cqlsh:blog_test> insert into posts(author,created_at,entry) values ('mike',minTimeuuid('2013-02-02 10:00+0000'),'This is an old entry by mike');
> cqlsh:blog_test> insert into posts(author,created_at,entry) values ('mike',minTimeuuid('2013-03-03 10:00+0000'),'This is a new entry by mike');
> cqlsh:blog_test> select * from posts limit 2;
> 
>  author | created_at                           | entry
> --------+--------------------------------------+------------------------------
>    mike | 1c4d9000-83e9-11e2-8080-808080808080 |  This is a new entry by mike
>    mike | 4e52d000-6d1f-11e2-8080-808080808080 | This is an old entry by mike



2014/05/16 23:54、Jonathan Lacefield <jl...@datastax.com> のメール:

> Hello,
> 
>  Have you looked at using the CLUSTERING ORDER BY and LIMIT features of CQL3?
> 
>  These may help you achieve your goals.
> 
>   http://www.datastax.com/documentation/cql/3.1/cql/cql_reference/refClstrOrdr.html
>   http://www.datastax.com/documentation/cql/3.1/cql/cql_reference/select_r.html
> 
> Jonathan Lacefield
> Solutions Architect, DataStax
> (404) 822 3487
> 
> 
> 
> 
> 
> 
> On Fri, May 16, 2014 at 12:23 AM, Matope Ono <ma...@gmail.com> wrote:
> Hi, I'm modeling some queries in CQL3.
> 
> I'd like to query first 1 columns for each partitioning keys in CQL3.
> 
> For example:
> 
> create table posts(
> 	author ascii,
> 	created_at timeuuid,
> 	entry text,
> 	primary key(author,created_at)
> );
> insert into posts(author,created_at,entry) values ('john',minTimeuuid('2013-02-02 10:00+0000'),'This is an old entry by john');
> insert into posts(author,created_at,entry) values ('john',minTimeuuid('2013-03-03 10:00+0000'),'This is a new entry by john');
> insert into posts(author,created_at,entry) values ('mike',minTimeuuid('2013-02-02 10:00+0000'),'This is an old entry by mike');
> insert into posts(author,created_at,entry) values ('mike',minTimeuuid('2013-03-03 10:00+0000'),'This is a new entry by mike');
> 
> And I want results like below.
> 
> mike,1c4d9000-83e9-11e2-8080-808080808080,This is a new entry by mike
> john,1c4d9000-83e9-11e2-8080-808080808080,This is a new entry by john
> 
> I think that this is what "SELECT FIRST " statements did in CQL2.
> 
> The only way I came across in CQL3 is "retrieve whole records and drop manually",
> but it's obviously not efficient.
> 
> Could you please tell me more straightforward way in CQL3?
> 


Re: Query first 1 columns for each partitioning keys in CQL?

Posted by Jonathan Lacefield <jl...@datastax.com>.
Hello,

 Have you looked at using the CLUSTERING ORDER BY and LIMIT features of
CQL3?

 These may help you achieve your goals.


http://www.datastax.com/documentation/cql/3.1/cql/cql_reference/refClstrOrdr.html

http://www.datastax.com/documentation/cql/3.1/cql/cql_reference/select_r.html

Jonathan Lacefield
Solutions Architect, DataStax
(404) 822 3487
<http://www.linkedin.com/in/jlacefield>

<http://www.datastax.com/cassandrasummit14>



On Fri, May 16, 2014 at 12:23 AM, Matope Ono <ma...@gmail.com> wrote:

> Hi, I'm modeling some queries in CQL3.
>
> I'd like to query first 1 columns for each partitioning keys in CQL3.
>
> For example:
>
> create table posts(
>> author ascii,
>> created_at timeuuid,
>> entry text,
>> primary key(author,created_at)
>> );
>> insert into posts(author,created_at,entry) values
>> ('john',minTimeuuid('2013-02-02 10:00+0000'),'This is an old entry by
>> john');
>> insert into posts(author,created_at,entry) values
>> ('john',minTimeuuid('2013-03-03 10:00+0000'),'This is a new entry by john');
>> insert into posts(author,created_at,entry) values
>> ('mike',minTimeuuid('2013-02-02 10:00+0000'),'This is an old entry by
>> mike');
>> insert into posts(author,created_at,entry) values
>> ('mike',minTimeuuid('2013-03-03 10:00+0000'),'This is a new entry by mike');
>
>
> And I want results like below.
>
> mike,1c4d9000-83e9-11e2-8080-808080808080,This is a new entry by mike
>> john,1c4d9000-83e9-11e2-8080-808080808080,This is a new entry by john
>
>
> I think that this is what "SELECT FIRST " statements did in CQL2.
>
> The only way I came across in CQL3 is "retrieve whole records and drop
> manually",
> but it's obviously not efficient.
>
> Could you please tell me more straightforward way in CQL3?
>