Map/reduce strategy to get the most recent open session document?

39 views
Skip to first unread message

Sebastien ARBOGAST

unread,
Jul 13, 2014, 4:59:40 PM7/13/14
to mobile-c...@googlegroups.com
I'm a total newbie with NoSQL DBs in general, and with Couchbase in particular. My main document type is a Session type. A Session document has a startDate, an endDate and an owner field.
Several sessions can be owned by the same user. A session is closed if it has an endDate. On one given device, a given user can only open a Session if it doesn't already have one open. But they can open a session on another device, which means I can have several open sessions in my database for any given owner. I want to retrieve the most recently open session for a given owner. I'm pretty sure it can be done with a clever map/reduce view, but I'm sill confused about how it works. Here is what I started doing in Objective-C:

[[database viewNamed:@"openByOwner"] setMapBlock:^(NSDictionary *doc, CBLMapEmitBlock emit) {
    if([doc[@"type"] isEqualToString:@"session"] && doc[@"endDate"] == nil){
        emit(doc[@"owner"], doc);
    }
} reduceBlock:^id(NSArray *keys, NSArray *values, BOOL rereduce) {
    return nil;
} version:@"1.0"];

With this I think I can filter my documents to get only open sessions, but how should I proceed to get only the one with the biggest start date for each owner in my query?

Jens Alfke

unread,
Jul 13, 2014, 7:22:42 PM7/13/14
to mobile-c...@googlegroups.com

On Jul 13, 2014, at 1:59 PM, Sebastien ARBOGAST <sebastien...@gmail.com> wrote:

With this I think I can filter my documents to get only open sessions, but how should I proceed to get only the one with the biggest start date for each owner in my query?

You probably want a view whose primary key is owner (because you want to query for a specific owner) and secondary key is date (because you want to sort by date.) The way you do that is by emitting a key that’s an array of the form @[owner, date]. That way you can query for all the rows with a specific owner, by specifying a key range, and the rows will end up sorted by date. If you only want the maximum date, then you just need to fetch the last row.

So in your query you set
descending = true // because you want to start with the max date
limit = 1 // because you only want the row with the max date
startKey = @[owner, @{}] // i.e. the last/max row with the given owner
endKey = @[owner] // i.e. the first row with the given owner

The @{} in the startKey is an idiom for “infinity”, because by the sorting rules a dictionary sorts after anything else. It’s commonly used as a placeholder when setting a range in a view that has array-based keys.

The docs for views and queries cover all of these concepts.

—Jens

Sebastien ARBOGAST

unread,
Jul 14, 2014, 3:12:47 AM7/14/14
to mobile-c...@googlegroups.com
Thanks a lot Jens. I have read all the docs and now I understand it but I definitely need some practice to learn how to put all this theory to work. Thanks for your help.

---
Sébastien Arbogast
http://sebastien-arbogast.com


--
You received this message because you are subscribed to the Google Groups "Couchbase Mobile" group.
To unsubscribe from this group and stop receiving emails from it, send an email to mobile-couchba...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/mobile-couchbase/13D1BD6E-1373-48AA-AD26-E484BF676B49%40couchbase.com.

For more options, visit https://groups.google.com/d/optout.

Reply all
Reply to author
Forward
0 new messages