You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@couchdb.apache.org by Troy Martin <tr...@scriptedmotion.com> on 2013/03/29 18:56:02 UTC

View collation question

I'm currently associating user documents with group documents like this:

{
   "_id": "544f4718732b51506d9de60a4e000505",
   "_rev": "137-f99f9a4aa5e3a4d48b76d98200b1f4fa",
   "username": "spencer",
   "firstName": "Spencer",
   "lastName": "jones",
   "emailAddress": "none@none.com",
   "roles": [
       "user"
   ],
   "type": "user",
   "disabled": false,
   "empId": "10"
},

{
   "_id": "3979684300c58a4c90c7c6e0d6035260",
   "_rev": "58-0df6c24716cd1768f668399a96059692",
   "type": "group",
   "name": "marina",
   "description": "",
   "users": [
       "544f4718732b51506d9de60a4e000505",
       "63de6351a30879ee091b248c930a9254",
       "8f87c698f119044890c5e788cd000c18",
       "4b95a2e0ec42cb6d49efac7f52000e2c",
       "8f87c698f119044890c5e788cd0019d7"
   ]
}


When I want to edit a user my app fetches the user document and a list of all the groups in the system. It then loops through the groups and pulls out the ones the user is associated with by looping through the users array looking for the users _id number. That's a lot of looping…8-) I have to have a list of groups anyway so the user can select from them, but I'm wondering if I can use view collation to fetch the user and their associated groups in one request to increase efficiency? I've looked at some examples on view collation, but the ones I've seen show a one to one relationship between documents. Not sure if I can use it with my data structured this way. I've considered a joining document like a joining table from sql, but thought I'd see if there was a way to make this work as is.

Thanks,

Troy




Re: View collation question

Posted by Jens Alfke <je...@couchbase.com>.
On Mar 29, 2013, at 10:56 AM, Troy Martin <tr...@scriptedmotion.com> wrote:

> I'm wondering if I can use view collation to fetch the user and their associated groups in one request to increase efficiency?

Sure; this is a pretty textbook example. Just write a map function that looks for group documents and emits keys that are pairs of the form [userid, groupid]. Then to find a user’s groups, query this view with a key range of startkey=[userid] and endkey=[userid, {}].

—Jens

Re: View collation question

Posted by Troy Martin <tr...@scriptedmotion.com>.
Wonderful! This works for me:

function(doc) {
  if(doc.type == 'user' && !doc.deletedAt) {
    emit(doc._id, null);
  }
  if(doc.type == 'group' && !doc.deletedAt) {
    for(var i = 0; i < doc.users.length; ++i) {
      emit(doc.users[i], null);
    }
  }
}

and I query it with the userID as the key:

http://localhost:5984/testing/_design/users/_view/byIdWithGroups?key="544f4718732b51506d9de60a4e000505"&include_docs=true

Best,

Troy

On Mar 29, 2013, at 11:34 AM, Paul Davis <pa...@gmail.com> wrote:

> On Fri, Mar 29, 2013 at 1:32 PM, svilen <az...@svilendobrev.com> wrote:
>> do these live in same table/database?
>> 
>> then it's possible in a view to have both user's-docs and
>> user's-group-docs, and fetch for key=user will give u the user and
>> all his groups.
>> something like (pseudocode)
>> 
>> if doc.type=="user": emit( doc.id, doc)
>> if doc.type=="group":
>>        for u in doc.users: emit( u, doc)
>> 
> 
> Depending on data sizes here you may just want to emit null and use
> the include_docs=true query string argument but other than that this
> is exactly what I was about to suggest.
> 
>> querying this with key=userid will yield the user-doc and the
>> group-docs for that user.
>> 
>> depends on what u really need, u can make something similar..
>> 
>> see
>> http://wiki.apache.org/couchdb/EntityRelationship
>> 
>> if these live in separate databases, then would be 2 queries - one for
>> user, one for groups for that userid.
>> 
>> ciao
>> svilen
>> 
>> On Fri, 29 Mar 2013 10:56:02 -0700
>> Troy Martin <tr...@scriptedmotion.com> wrote:
>> 
>>> I'm currently associating user documents with group documents like
>>> this:
>>> 
>>> {
>>>   "_id": "544f4718732b51506d9de60a4e000505",
>>>   "_rev": "137-f99f9a4aa5e3a4d48b76d98200b1f4fa",
>>>   "username": "spencer",
>>>   "firstName": "Spencer",
>>>   "lastName": "jones",
>>>   "emailAddress": "none@none.com",
>>>   "roles": [
>>>       "user"
>>>   ],
>>>   "type": "user",
>>>   "disabled": false,
>>>   "empId": "10"
>>> },
>>> 
>>> {
>>>   "_id": "3979684300c58a4c90c7c6e0d6035260",
>>>   "_rev": "58-0df6c24716cd1768f668399a96059692",
>>>   "type": "group",
>>>   "name": "marina",
>>>   "description": "",
>>>   "users": [
>>>       "544f4718732b51506d9de60a4e000505",
>>>       "63de6351a30879ee091b248c930a9254",
>>>       "8f87c698f119044890c5e788cd000c18",
>>>       "4b95a2e0ec42cb6d49efac7f52000e2c",
>>>       "8f87c698f119044890c5e788cd0019d7"
>>>   ]
>>> }
>>> 
>>> 
>>> When I want to edit a user my app fetches the user document and a
>>> list of all the groups in the system. It then loops through the
>>> groups and pulls out the ones the user is associated with by looping
>>> through the users array looking for the users _id number. That's a
>>> lot of looping…8-) I have to have a list of groups anyway so the user
>>> can select from them, but I'm wondering if I can use view collation
>>> to fetch the user and their associated groups in one request to
>>> increase efficiency? I've looked at some examples on view collation,
>>> but the ones I've seen show a one to one relationship between
>>> documents. Not sure if I can use it with my data structured this way.
>>> I've considered a joining document like a joining table from sql, but
>>> thought I'd see if there was a way to make this work as is.
>>> 
>>> Thanks,
>>> 
>>> Troy
>>> 
>>> 
>>> 


Re: View collation question

Posted by Paul Davis <pa...@gmail.com>.
On Fri, Mar 29, 2013 at 1:32 PM, svilen <az...@svilendobrev.com> wrote:
> do these live in same table/database?
>
> then it's possible in a view to have both user's-docs and
> user's-group-docs, and fetch for key=user will give u the user and
> all his groups.
> something like (pseudocode)
>
>  if doc.type=="user": emit( doc.id, doc)
>  if doc.type=="group":
>         for u in doc.users: emit( u, doc)
>

Depending on data sizes here you may just want to emit null and use
the include_docs=true query string argument but other than that this
is exactly what I was about to suggest.

> querying this with key=userid will yield the user-doc and the
> group-docs for that user.
>
> depends on what u really need, u can make something similar..
>
> see
> http://wiki.apache.org/couchdb/EntityRelationship
>
> if these live in separate databases, then would be 2 queries - one for
> user, one for groups for that userid.
>
> ciao
> svilen
>
> On Fri, 29 Mar 2013 10:56:02 -0700
> Troy Martin <tr...@scriptedmotion.com> wrote:
>
>> I'm currently associating user documents with group documents like
>> this:
>>
>> {
>>    "_id": "544f4718732b51506d9de60a4e000505",
>>    "_rev": "137-f99f9a4aa5e3a4d48b76d98200b1f4fa",
>>    "username": "spencer",
>>    "firstName": "Spencer",
>>    "lastName": "jones",
>>    "emailAddress": "none@none.com",
>>    "roles": [
>>        "user"
>>    ],
>>    "type": "user",
>>    "disabled": false,
>>    "empId": "10"
>> },
>>
>> {
>>    "_id": "3979684300c58a4c90c7c6e0d6035260",
>>    "_rev": "58-0df6c24716cd1768f668399a96059692",
>>    "type": "group",
>>    "name": "marina",
>>    "description": "",
>>    "users": [
>>        "544f4718732b51506d9de60a4e000505",
>>        "63de6351a30879ee091b248c930a9254",
>>        "8f87c698f119044890c5e788cd000c18",
>>        "4b95a2e0ec42cb6d49efac7f52000e2c",
>>        "8f87c698f119044890c5e788cd0019d7"
>>    ]
>> }
>>
>>
>> When I want to edit a user my app fetches the user document and a
>> list of all the groups in the system. It then loops through the
>> groups and pulls out the ones the user is associated with by looping
>> through the users array looking for the users _id number. That's a
>> lot of looping…8-) I have to have a list of groups anyway so the user
>> can select from them, but I'm wondering if I can use view collation
>> to fetch the user and their associated groups in one request to
>> increase efficiency? I've looked at some examples on view collation,
>> but the ones I've seen show a one to one relationship between
>> documents. Not sure if I can use it with my data structured this way.
>> I've considered a joining document like a joining table from sql, but
>> thought I'd see if there was a way to make this work as is.
>>
>> Thanks,
>>
>> Troy
>>
>>
>>

Re: View collation question

Posted by svilen <az...@svilendobrev.com>.
do these live in same table/database?

then it's possible in a view to have both user's-docs and
user's-group-docs, and fetch for key=user will give u the user and
all his groups.
something like (pseudocode)

 if doc.type=="user": emit( doc.id, doc)
 if doc.type=="group": 
	for u in doc.users: emit( u, doc)

querying this with key=userid will yield the user-doc and the
group-docs for that user.

depends on what u really need, u can make something similar..

see
http://wiki.apache.org/couchdb/EntityRelationship

if these live in separate databases, then would be 2 queries - one for
user, one for groups for that userid.

ciao
svilen

On Fri, 29 Mar 2013 10:56:02 -0700
Troy Martin <tr...@scriptedmotion.com> wrote:

> I'm currently associating user documents with group documents like
> this:
> 
> {
>    "_id": "544f4718732b51506d9de60a4e000505",
>    "_rev": "137-f99f9a4aa5e3a4d48b76d98200b1f4fa",
>    "username": "spencer",
>    "firstName": "Spencer",
>    "lastName": "jones",
>    "emailAddress": "none@none.com",
>    "roles": [
>        "user"
>    ],
>    "type": "user",
>    "disabled": false,
>    "empId": "10"
> },
> 
> {
>    "_id": "3979684300c58a4c90c7c6e0d6035260",
>    "_rev": "58-0df6c24716cd1768f668399a96059692",
>    "type": "group",
>    "name": "marina",
>    "description": "",
>    "users": [
>        "544f4718732b51506d9de60a4e000505",
>        "63de6351a30879ee091b248c930a9254",
>        "8f87c698f119044890c5e788cd000c18",
>        "4b95a2e0ec42cb6d49efac7f52000e2c",
>        "8f87c698f119044890c5e788cd0019d7"
>    ]
> }
> 
> 
> When I want to edit a user my app fetches the user document and a
> list of all the groups in the system. It then loops through the
> groups and pulls out the ones the user is associated with by looping
> through the users array looking for the users _id number. That's a
> lot of looping…8-) I have to have a list of groups anyway so the user
> can select from them, but I'm wondering if I can use view collation
> to fetch the user and their associated groups in one request to
> increase efficiency? I've looked at some examples on view collation,
> but the ones I've seen show a one to one relationship between
> documents. Not sure if I can use it with my data structured this way.
> I've considered a joining document like a joining table from sql, but
> thought I'd see if there was a way to make this work as is.
> 
> Thanks,
> 
> Troy
> 
> 
>