You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@couchdb.apache.org by Sho Fukamachi <sh...@gmail.com> on 2009/03/19 06:17:31 UTC

view collation/filtering with key arrays

Hi all,

This has been bugging me for a while now. I don't understand how view  
collation is supposed to work when there's an array of startkeys and  
endkeys. I've been working around it, but thought "time to ask the  
list".

Say we have a list of Artists:

{
    "name": "Spice Girls",
    "country": "UK",
    "type": "artist",
    "genre": "Pop",
}

{
    "name": "Hannah Montana",
    "country": "USA",
    "type": "artist",
    "genre": "Pop",
}

{
    "name": "Def Leppard",
    "country": "USA",
    "type": "artist",
    "genre": "Rock",
}

We then make a basic view to find by genre and country:

function(doc) {
   if (doc.type == 'artist' )
     emit([doc.genre, doc.country], doc.name);
     }

Now let's test:

 >> Artist.find_by_genre_country :country => "USA", :genre => "Rock"
key array: [["Rock", "USA"], ["Rock", "USA"]]
=> ["Def Leppard"]

Awesome. What's the best pop act in Britain?

 >> Artist.find_by_genre_country :country => "UK", :genre => "Pop"
key array: [["Pop", "UK"], ["Pop", "UK"]]
=> ["Spice Girls"]

Thought so. How about all worthwhile Pop acts?

 >> Artist.find_by_genre_country :genre => "Pop"
key array: [["Pop", nil], ["Pop", {}]]
=> ["Spice Girls", "Hannah Montana"]

There you have it. Filtering on the left side works. How about all  
artists in the USA?

 >> Artist.find_by_genre_country :country => "USA"
key array: [[nil, "USA"], [{}, "USA"]]
=> ["Spice Girls", "Hannah Montana", "Def Leppard"]

Huh?

What am I missing here? Am I doing something wrong, or is "filtering"  
only available left-to-right? Does it stop when it hits a "wildcard"  
like the NULL/{} trick?

I actually have worked around it, but have been wondering about this  
for a long time. Sorry if it's a really stupid question and I have  
missed something incredibly obvious...

thanks a lot.

Sho


Re: view collation/filtering with key arrays

Posted by Jason Smith <jh...@proven-corporation.com>.
Sho Fukamachi wrote:
> It seems obvious when you look at it but still seems counterintuitive to 
> me. I guess I just couldn't get my head around how it is able to refine 
> the sort on the right hand side, under certain circumstances, but didn't 
> seem able to do it when the "infinity" sorters were there .. I'll 
> probably have to write out some solution sets or something before I can 
> really internalise it.

Yes, the key is to remember that no matter how clever you get, views are 
ultimately a one-dimensional representation of your data.  If you need 
queries on more than one variable, you will need multiple queries 
against multiple views, or perhaps take another route like 
couchdb-lucene, which is quite nice.

-- 
Jason Smith
Proven Corporation
Bangkok, Thailand
http://www.proven-corporation.com

Re: view collation/filtering with key arrays

Posted by Sho Fukamachi <sh...@gmail.com>.
On 19/03/2009, at 4:44 PM, Brenton Alker wrote:
>
> Hope that makes some sense, and is relatively correct (if  
> oversimplified).

Hm. It does make some sense - thanks for the explanation. I guess I  
was (still am, heh) having difficulty conceptualising it.

It seems obvious when you look at it but still seems counterintuitive  
to me. I guess I just couldn't get my head around how it is able to  
refine the sort on the right hand side, under certain circumstances,  
but didn't seem able to do it when the "infinity" sorters were  
there .. I'll probably have to write out some solution sets or  
something before I can really internalise it.

Anyway thanks a lot for the explanation. And good to see fellow  
Aussies on the list!

Sho




> -- 
>
> Brenton Alker
> PHP Developer - Brisbane, Australia
>
> http://blog.tekerson.com/
>


Re: view collation/filtering with key arrays

Posted by Brenton Alker <br...@tekerson.com>.
Sho Fukamachi wrote:
> Hi all,
> 
> This has been bugging me for a while now. I don't understand how view
> collation is supposed to work when there's an array of startkeys and
> endkeys. I've been working around it, but thought "time to ask the list".
> 
> Say we have a list of Artists:
> 
> {
>    "name": "Spice Girls",
>    "country": "UK",
>    "type": "artist",
>    "genre": "Pop",
> }
> 
> {
>    "name": "Hannah Montana",
>    "country": "USA",
>    "type": "artist",
>    "genre": "Pop",
> }
> 
> {
>    "name": "Def Leppard",
>    "country": "USA",
>    "type": "artist",
>    "genre": "Rock",
> }
> 
> We then make a basic view to find by genre and country:
> 
> function(doc) {
>   if (doc.type == 'artist' )
>     emit([doc.genre, doc.country], doc.name);
>     }
> 
> Now let's test:
> 
>>> Artist.find_by_genre_country :country => "USA", :genre => "Rock"
> key array: [["Rock", "USA"], ["Rock", "USA"]]
> => ["Def Leppard"]
> 
> Awesome. What's the best pop act in Britain?
> 
>>> Artist.find_by_genre_country :country => "UK", :genre => "Pop"
> key array: [["Pop", "UK"], ["Pop", "UK"]]
> => ["Spice Girls"]
> 
> Thought so. How about all worthwhile Pop acts?
> 
>>> Artist.find_by_genre_country :genre => "Pop"
> key array: [["Pop", nil], ["Pop", {}]]
> => ["Spice Girls", "Hannah Montana"]
> 
> There you have it. Filtering on the left side works. How about all
> artists in the USA?
> 
>>> Artist.find_by_genre_country :country => "USA"
> key array: [[nil, "USA"], [{}, "USA"]]
> => ["Spice Girls", "Hannah Montana", "Def Leppard"]
> 
> Huh?
> 
> What am I missing here? Am I doing something wrong, or is "filtering"
> only available left-to-right? Does it stop when it hits a "wildcard"
> like the NULL/{} trick?
> 
> I actually have worked around it, but have been wondering about this for
> a long time. Sorry if it's a really stupid question and I have missed
> something incredibly obvious...
> 
> thanks a lot.
> 
> Sho
> 

In my (admittedly limited) understanding, the view you have created has
effectively created an index that is sorted by genre, country. Which is
to say, sort by genre then inside that country. So the index would look
like:
["Pop", "UK"]
["Pop", "USA"]
["Rock", "USA"]

The key you are using to query is setting the start and end points (nil
and {} are used because they are sorted before and after scalars
respectively).

The query [["Pop", nil], ["Pop", {}]] will give you everything between
those 2 value. ie. ["Pop", "UK"] and ["Pop", "USA"] (or the associated
values anyway)

So, your query for [[nil, "USA"], [{}, "USA"]] will return everything,
yes. Because everything sorts between those two values.

Hope that makes some sense, and is relatively correct (if oversimplified).

-- 

Brenton Alker
PHP Developer - Brisbane, Australia

http://blog.tekerson.com/


Re: view collation/filtering with key arrays

Posted by Paul Carey <pa...@gmail.com>.
Hi Sho

Adam and Paul Davis also offered explanations for this a little while back.
http://www.mail-archive.com/user@couchdb.apache.org/msg00014.html

Paul

On Thu, Mar 19, 2009 at 5:17 AM, Sho Fukamachi <sh...@gmail.com> wrote:
> Hi all,
>
> This has been bugging me for a while now. I don't understand how view
> collation is supposed to work when there's an array of startkeys and
> endkeys. I've been working around it, but thought "time to ask the list".
>
> Say we have a list of Artists:
>
> {
>   "name": "Spice Girls",
>   "country": "UK",
>   "type": "artist",
>   "genre": "Pop",
> }
>
> {
>   "name": "Hannah Montana",
>   "country": "USA",
>   "type": "artist",
>   "genre": "Pop",
> }
>
> {
>   "name": "Def Leppard",
>   "country": "USA",
>   "type": "artist",
>   "genre": "Rock",
> }
>
> We then make a basic view to find by genre and country:
>
> function(doc) {
>  if (doc.type == 'artist' )
>    emit([doc.genre, doc.country], doc.name);
>    }
>
> Now let's test:
>
>>> Artist.find_by_genre_country :country => "USA", :genre => "Rock"
> key array: [["Rock", "USA"], ["Rock", "USA"]]
> => ["Def Leppard"]
>
> Awesome. What's the best pop act in Britain?
>
>>> Artist.find_by_genre_country :country => "UK", :genre => "Pop"
> key array: [["Pop", "UK"], ["Pop", "UK"]]
> => ["Spice Girls"]
>
> Thought so. How about all worthwhile Pop acts?
>
>>> Artist.find_by_genre_country :genre => "Pop"
> key array: [["Pop", nil], ["Pop", {}]]
> => ["Spice Girls", "Hannah Montana"]
>
> There you have it. Filtering on the left side works. How about all artists
> in the USA?
>
>>> Artist.find_by_genre_country :country => "USA"
> key array: [[nil, "USA"], [{}, "USA"]]
> => ["Spice Girls", "Hannah Montana", "Def Leppard"]
>
> Huh?
>
> What am I missing here? Am I doing something wrong, or is "filtering" only
> available left-to-right? Does it stop when it hits a "wildcard" like the
> NULL/{} trick?
>
> I actually have worked around it, but have been wondering about this for a
> long time. Sorry if it's a really stupid question and I have missed
> something incredibly obvious...
>
> thanks a lot.
>
> Sho
>
>