You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@couchdb.apache.org by Patrick Barnes <mr...@gmail.com> on 2010/02/01 07:43:29 UTC

Trees and leaf nodes

I have a large tree of documents that I want to display in a dynamic 
treeview, but I'm not sure how best to determine whether a given node 
has children or not.

Each document has a 'path' element giving it's place in the tree, eg 
this following doc has the parent 'AA', which in turn has the top-level 
parent 'A'.
doc = {
     '_id':'11203',
     'path':['A','AA','11203']
     ...
};

Fetching and displaying the entire tree is simple... this view:
function(doc) { emit(doc.path, doc.display_name); }
emits in lexicographical order, and some php code turns it into a nested 
list.

The entire tree is slow to retrieve and display in one go. With jquery 
treeview-async, I retrieve and display only the top-level nodes on page 
load, then on expanding a node it will call the server with the ID, 
asking for children.

I have a view that returns just the immediate children of the given key:
function(doc) {
	if (doc.doc_type=='group') {
		//Emit the path of the parent...
		doc.path.pop();
		emit(doc.path, doc.display_name);
	}
}
So things mostly work nicely - I can click on a node, and it will 
dynamically load children, rinse, repeat.

It looks messy if the node has a little 'expand' icon next to it, though 
- but there are no actual children below it. Is it possible to create a 
view that will emit as value whether each node has children?

Cheers,
-Patrick Barnes

Re: Trees and leaf nodes

Posted by Adam Wolff <aw...@gmail.com>.
If you only care about whether or not there are children, you could reduce
to the count of children for each key.

A

On Mon, Feb 1, 2010 at 5:15 AM, Patrick Barnes <mr...@gmail.com> wrote:

> Thanks, that sounds like should work. The only boundary case for a query to
> get the number of children is that if there are no children for that key it
> will return a blank result, not a '0' record.
>
> I thought - hey, if I only cared about presence or absence of children I
> could just use the get_children view, passing it key=$parent_id & limit=0
> ... but the view summary (at least in 0.10.0) only returns total row count
> and offset, not how many rows would have been returned if limit=0 had not
> been present.
>
> ... okay, having just typed the last paragraph I realise - even if
> feasible, that would only work using one key at a time. *yawns*
>
> But the grouped query makes sense, I'll test it tomorrow.
>
> -P
>
>
>
> On 1/02/2010 10:04 PM, Brian Candler wrote:
>
>> On Mon, Feb 01, 2010 at 05:43:29PM +1100, Patrick Barnes wrote:
>>
>>> It looks messy if the node has a little 'expand' icon next to it,
>>> though - but there are no actual children below it. Is it possible
>>> to create a view that will emit as value whether each node has
>>> children?
>>>
>>
>> I think the client needs to make two queries. Under a given node:
>>
>> 1. Get the list of the children
>> 2. Determine whether each child also has children
>>
>> You can do (2) using a single multi-key query, e.g.
>>
>>   {keys:[c1, c2, c3, ...]}
>>
>> Using your existing view you'll get all the grandchildren, which you
>> probably don't care about but can just check whether there are any or not.
>>
>> To reduce the size of the returned data you could make a grouped query
>> instead.  With a suitable reduce function on your view, then you could get
>> back a count of the number of children for each child, which might be
>> useful
>> to display in your UI anyway.
>>
>> HTH,
>>
>> Brian.
>>
>>

Re: Trees and leaf nodes

Posted by Patrick Barnes <mr...@gmail.com>.
Thanks, that sounds like should work. The only boundary case for a query 
to get the number of children is that if there are no children for that 
key it will return a blank result, not a '0' record.

I thought - hey, if I only cared about presence or absence of children I 
could just use the get_children view, passing it key=$parent_id & 
limit=0 ... but the view summary (at least in 0.10.0) only returns total 
row count and offset, not how many rows would have been returned if 
limit=0 had not been present.

... okay, having just typed the last paragraph I realise - even if 
feasible, that would only work using one key at a time. *yawns*

But the grouped query makes sense, I'll test it tomorrow.

-P


On 1/02/2010 10:04 PM, Brian Candler wrote:
> On Mon, Feb 01, 2010 at 05:43:29PM +1100, Patrick Barnes wrote:
>> It looks messy if the node has a little 'expand' icon next to it,
>> though - but there are no actual children below it. Is it possible
>> to create a view that will emit as value whether each node has
>> children?
>
> I think the client needs to make two queries. Under a given node:
>
> 1. Get the list of the children
> 2. Determine whether each child also has children
>
> You can do (2) using a single multi-key query, e.g.
>
>    {keys:[c1, c2, c3, ...]}
>
> Using your existing view you'll get all the grandchildren, which you
> probably don't care about but can just check whether there are any or not.
>
> To reduce the size of the returned data you could make a grouped query
> instead.  With a suitable reduce function on your view, then you could get
> back a count of the number of children for each child, which might be useful
> to display in your UI anyway.
>
> HTH,
>
> Brian.
>

Re: Trees and leaf nodes

Posted by Brian Candler <B....@pobox.com>.
On Mon, Feb 01, 2010 at 05:43:29PM +1100, Patrick Barnes wrote:
> It looks messy if the node has a little 'expand' icon next to it,
> though - but there are no actual children below it. Is it possible
> to create a view that will emit as value whether each node has
> children?

I think the client needs to make two queries. Under a given node:

1. Get the list of the children
2. Determine whether each child also has children

You can do (2) using a single multi-key query, e.g.

  {keys:[c1, c2, c3, ...]}

Using your existing view you'll get all the grandchildren, which you
probably don't care about but can just check whether there are any or not.

To reduce the size of the returned data you could make a grouped query
instead.  With a suitable reduce function on your view, then you could get
back a count of the number of children for each child, which might be useful
to display in your UI anyway.

HTH,

Brian.