You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@couchdb.apache.org by Borja Martín <bo...@dagi3d.net> on 2009/12/24 01:47:33 UTC

sorting documents using multiple keys

Hi,
I'm pretty new to couchdb and I'm not quite sure if this can be done. Is
there any way to sort the retrieved documents by a certain field when I
select them using multiple keys?
I have these documents for example:
{
  _id : "a",
  tags : ["foo"],
  created_at : "20091201"
},

{
  _id : "b",
  tags  : ["bar"],
  created_at : "20091231"
},

{
  _id : "c",
  tags  : ["foo", "bar"],
  created_at : "20091215"
},


Then, I create a view to store the documents for each tag:

function(doc) {
    for(var idx in doc.tags) {
      emit(doc.tags[idx], doc);
    }
  }

and eventually I can make a POST request using the keys parameter in order
the retrieve all the documents that have one or more of the given tags.
The problem is that I don't know how to sort the result by the field
created_at and I can't use it in the emit function within the key as I will
not know the value for it (and the documents can different values for it)

Any idea how to achieve this?

Thanks in advance

Regards
-- 
def dagi3d(me)
 case me
   when :web then  "http://dagi3d.net"
   when :twitter then "http://twitter.com/dagi3d"
 end
end

Re: sorting documents using multiple keys

Posted by Chris Anderson <jc...@apache.org>.
On Fri, Dec 25, 2009 at 7:53 AM, Borja Martín <bo...@dagi3d.net> wrote:
> Hi,
> by the moment this isn't a solution as we will work with a large dataset.
> Probably we could preprocess the result and store it as cache as you
> suggested but I think a native solution from couchdb would be fine.
>

There are widespread requests for an enhancement to the multi-key
query feature, which would allow you to POST a collection of queries
(start and end key, limit, etc).

See:

http://issues.apache.org/jira/browse/COUCHDB-523

and

http://issues.apache.org/jira/browse/COUCHDB-137

I haven't written this patch because it is fairly trivial and would be
a good place for a new developer to get started with hacking on
CouchDB.

So, to be clear, many people are having the same issue as you. We're
just waiting for someone to write the patch.

If anyone wants to approach this, please bring it up on the dev@ list
and we'll be glad to help you orient yourself.

Cheers,
Chris

> Regards
>
> On Thu, Dec 24, 2009 at 1:07 PM, Patrick Barnes <mr...@gmail.com> wrote:
>
>> Perhaps if you have a document set small enough to retrieve by explicit
>> keys, you can just sort by date on the client?
>>
>> -Patrick
>>
>> On 24/12/2009 9:17 PM, "Borja Martín" <bo...@dagi3d.net> wrote:
>>
>> Hi,
>> thanks for your answer. The thing is that this solution only works for
>> single keys and I can't use the startkey/endkey params in the POST request
>> with the 'keys' param in order to query for multi keys
>>
>> (Thanks for the include_docs tip :))
>>
>> Regards
>>
>> On Thu, Dec 24, 2009 at 3:43 AM, Anand Chitipothu <anandology@gmail.com
>> >wrote:
>>
>> > > Then, I create a view to store the documents for each tag: > > > >
>> function(doc) { > > for(v...
>>
>> -- def dagi3d(me) case me when :web then "http://dagi3d.net" when :twitter
>> then "http://twi...
>>
>
>
>
> --
> def dagi3d(me)
>  case me
>   when :web then  "http://dagi3d.net"
>   when :twitter then "http://twitter.com/dagi3d"
>  end
> end
>



-- 
Chris Anderson
http://jchrisa.net
http://couch.io

Re: sorting documents using multiple keys

Posted by Borja Martín <bo...@dagi3d.net>.
Hi,
by the moment this isn't a solution as we will work with a large dataset.
Probably we could preprocess the result and store it as cache as you
suggested but I think a native solution from couchdb would be fine.

Regards

On Thu, Dec 24, 2009 at 1:07 PM, Patrick Barnes <mr...@gmail.com> wrote:

> Perhaps if you have a document set small enough to retrieve by explicit
> keys, you can just sort by date on the client?
>
> -Patrick
>
> On 24/12/2009 9:17 PM, "Borja Martín" <bo...@dagi3d.net> wrote:
>
> Hi,
> thanks for your answer. The thing is that this solution only works for
> single keys and I can't use the startkey/endkey params in the POST request
> with the 'keys' param in order to query for multi keys
>
> (Thanks for the include_docs tip :))
>
> Regards
>
> On Thu, Dec 24, 2009 at 3:43 AM, Anand Chitipothu <anandology@gmail.com
> >wrote:
>
> > > Then, I create a view to store the documents for each tag: > > > >
> function(doc) { > > for(v...
>
> -- def dagi3d(me) case me when :web then "http://dagi3d.net" when :twitter
> then "http://twi...
>



-- 
def dagi3d(me)
 case me
   when :web then  "http://dagi3d.net"
   when :twitter then "http://twitter.com/dagi3d"
 end
end

Re: sorting documents using multiple keys

Posted by Patrick Barnes <mr...@gmail.com>.
Perhaps if you have a document set small enough to retrieve by explicit
keys, you can just sort by date on the client?

-Patrick

On 24/12/2009 9:17 PM, "Borja Martín" <bo...@dagi3d.net> wrote:

Hi,
thanks for your answer. The thing is that this solution only works for
single keys and I can't use the startkey/endkey params in the POST request
with the 'keys' param in order to query for multi keys

(Thanks for the include_docs tip :))

Regards

On Thu, Dec 24, 2009 at 3:43 AM, Anand Chitipothu <anandology@gmail.com
>wrote:

> > Then, I create a view to store the documents for each tag: > > > >
function(doc) { > > for(v...

-- def dagi3d(me) case me when :web then "http://dagi3d.net" when :twitter
then "http://twi...

Re: sorting documents using multiple keys

Posted by Borja Martín <bo...@dagi3d.net>.
Hi,
thanks for your answer. The thing is that this solution only works for
single keys and I can't use the startkey/endkey params in the POST request
with the 'keys' param in order to query for multi keys

(Thanks for the include_docs tip :))

Regards

On Thu, Dec 24, 2009 at 3:43 AM, Anand Chitipothu <an...@gmail.com>wrote:

> > Then, I create a view to store the documents for each tag:
> >
> > function(doc) {
> >    for(var idx in doc.tags) {
> >      emit(doc.tags[idx], doc);
> >    }
> >  }
> >
> > and eventually I can make a POST request using the keys parameter in
> order
> > the retrieve all the documents that have one or more of the given tags.
> > The problem is that I don't know how to sort the result by the field
> > created_at and I can't use it in the emit function within the key as I
> will
> > not know the value for it (and the documents can different values for it)
> >
> > Any idea how to achieve this?
>
> Change your view function to emit both tag and created_at.
>
> function (doc) {
>    for (var i in doc.tags) {
>        emit([doc.tags[i], doc.created_at], null);
>    }
> }
>
> Also notice that you don't have to emit the doc. It can be included in
> the result by adding "include_docs=true" to your query string.
>
> Use the following request to get all documents, matching a tag.
>
> http://localhost:5984/
> <dbname>/_design/<design-doc-name>/<viewname>?start_key=["mytag"]&end_key=["mytag",
> {}]&include_docs=true
>
> If you want the most recent doc first, try adding descending=true and
> swap start_key and end_key.
>
> I'm not sure if there is any straight-forward way to query for more
> than one tag. You can probably achieve that by making your view
> function emit all possible combinations of tags in the document.
>
> Anand
>



-- 
def dagi3d(me)
 case me
   when :web then  "http://dagi3d.net"
   when :twitter then "http://twitter.com/dagi3d"
 end
end

Re: sorting documents using multiple keys

Posted by Anand Chitipothu <an...@gmail.com>.
> Then, I create a view to store the documents for each tag:
>
> function(doc) {
>    for(var idx in doc.tags) {
>      emit(doc.tags[idx], doc);
>    }
>  }
>
> and eventually I can make a POST request using the keys parameter in order
> the retrieve all the documents that have one or more of the given tags.
> The problem is that I don't know how to sort the result by the field
> created_at and I can't use it in the emit function within the key as I will
> not know the value for it (and the documents can different values for it)
>
> Any idea how to achieve this?

Change your view function to emit both tag and created_at.

function (doc) {
    for (var i in doc.tags) {
        emit([doc.tags[i], doc.created_at], null);
    }
}

Also notice that you don't have to emit the doc. It can be included in
the result by adding "include_docs=true" to your query string.

Use the following request to get all documents, matching a tag.

http://localhost:5984/<dbname>/_design/<design-doc-name>/<viewname>?start_key=["mytag"]&end_key=["mytag",
{}]&include_docs=true

If you want the most recent doc first, try adding descending=true and
swap start_key and end_key.

I'm not sure if there is any straight-forward way to query for more
than one tag. You can probably achieve that by making your view
function emit all possible combinations of tags in the document.

Anand