Workaround the inability to traverse into doc pointers in map function.

14 views
Skip to first unread message

Traun Leyden

unread,
Oct 24, 2014, 6:44:58 PM10/24/14
to mobile-c...@googlegroups.com

I'm working on some changes for the officeradar demo app and trying to show a list of profiles which I want to have reverse sorted by how recent they've had a geofence event for that profile.  Eg: 

[Traun entered SF 5 hours ago]
[Zack entered SF 8 hours ago]
[Hideki entered MV 2 days ago]

The document model is as follows:

Profile doc

{  
   "_id":"tleyden",
   "lastGeofenceEvent":"doc-234324232" 
}

GeofenceEvent doc

{  
   "id":"doc-234324232",
   "createdAt":"2014-10-24",
   "beaconLocation":"sf"
}


As I was writing the map function to generate the UI mentioned above, I wanted to emit the createdAt field, but realized that would require a doc lookup.  Eg:

Mapper map = new Mapper() {
                @Override
                public void map(Map<String, Object> document, Emitter emitter) {
                    if (document.get("type").equals("profile")) {

                        // I have a profile doc, but I only have the id of the
                        // latest geofence event associated with this profile,
                        // and I'd need to do a db lookup to get it, which
                        // would violate the rules of a map function .. so I'm stuck

                    }
                }
            };

Proposed solution

I figured I could add a new field to the profile doc to hold the date of the latest geofence event associated with this profile (denormalize + duplicate):

Profile doc (updated):

{  
   "_id":"tleyden",
   "lastGeofenceEvent":"doc-234324232",
   "lastGeofenceEventCreatedAt":"2014-10-24"
}

The map function would become:
 
                  if (document.get("type").equals("profile")) {

                        emit(document.get("lastGeofenceEventCreatedAt"), ...);

                   }

and the problem would be solved.

But, I'm wondering is this the best practice or is there a better way?  @Jens I remember in your advanced couchbase lite talk you mentioned "poor man's joins", but I didn't catch the details.  Would that apply here? 

Zack Gramana

unread,
Oct 24, 2014, 6:47:33 PM10/24/14
to mobile-c...@googlegroups.com
+1 for adding doc pointer de-referencing before calling the map function.

--
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/CACSSHCEyDD2EdKYVERZAcdG5N5VjonGaeHSW1mntX8DXeWYLTw%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

Matt Quinn

unread,
Oct 24, 2014, 7:25:32 PM10/24/14
to mobile-c...@googlegroups.com
On Fri, Oct 24, 2014 at 10:47:25PM +0000, Zack Gramana wrote:
> +1 for adding doc pointer de-referencing before calling the map function.

Keep in mind the classic counter-argument from CouchDB about referencing
external docs in map functions: map results are persisted at whatever
time they're first calculated for a particular revision, so this makes
the values in the view time-dependent. They would contain whatever
properties the linked document happened to have at the time the index
was run, and wouldn't change if the linked document changed. It also
means that two replicating databases may have different view results
with the same DB contents, if the two databases got their updates in a
different order.

> On Oct 24, 2014, at 3:44 PM, Traun Leyden <tle...@couchbase.com<mailto:tle...@couchbase.com>> wrote:
> But, I'm wondering is this the best practice or is there a better way?
> @Jens I remember in your advanced couchbase lite talk you mentioned
> "poor man's joins", but I didn't catch the details. Would that apply
> here?

I haven't had a chance to watch the talk yet (so pardon me if I'm way
off-base), but usually Couch's "poor-man's joins" refers to the use of
either linked documents[0] or view collation tricks[1] to get both the
doc you're looking for and its related documents in the same view query.
Those are both options that might be preferable to deduping the data.

[0] http://wiki.apache.org/couchdb/Introduction_to_CouchDB_views#Linked_documents
[1] http://www.cmlenz.net/archives/2007/10/couchdb-joins (see section
"Optimization: Using the Power of View Collation")

-
Matt

Jens Alfke

unread,
Oct 24, 2014, 7:55:13 PM10/24/14
to mobile-c...@googlegroups.com

On Oct 24, 2014, at 4:25 PM, Matt Quinn <ma...@mjquinn.ca> wrote:

I haven't had a chance to watch the talk yet (so pardon me if I'm way
off-base), but usually Couch's "poor-man's joins" refers to the use of
either linked documents[0] or view collation tricks[1] to get both the
doc you're looking for and its related documents in the same view query.

Yup. (That's a great article you linked to, btw.) I think this technique might be useful in Traun's case, but I don't have the cycles to examine it myself right now…

—Jens
Reply all
Reply to author
Forward
0 new messages