Split Document in Two?

38 views
Skip to first unread message

Steve

unread,
Sep 22, 2014, 7:55:14 AM9/22/14
to mobile-c...@googlegroups.com
The central "model" object (as in MVC) in my app has ten strings properties and one dictionary property. The string properties rarely change (i.e. would be updated only a few times a year). The dictionary property contains three numeric values which could change several times a day, somewhere between twelve times a day (e.g. every hour) to 144 times a day (e.g. every five minutes).

Is it worth separating out the dictionary with its three properties into a separate document and linking this new document type back to the document with the static string properties? This seems appealing as it will reduce the traffic (at least in relative terms) between the remote Couchbase Server and the phone (all changes would originate on the Couchbase Server), but if the objects in my app are subclasses of CBLModel it seems like it would be a headache to "join" the documents together on the phone to create an object with both the static and non-static properties.

Not sure if the above is clear...

Any advice?

Jens Alfke

unread,
Sep 22, 2014, 2:47:40 PM9/22/14
to mobile-c...@googlegroups.com
On Sep 22, 2014, at 4:55 AM, Steve <s.ande...@gmail.com> wrote:

Is it worth separating out the dictionary with its three properties into a separate document and linking this new document type back to the document with the static string properties?

Depends on how big the rarely-changing data is. (And on how many of these docs there are.)

if the objects in my app are subclasses of CBLModel it seems like it would be a headache to "join" the documents together on the phone to create an object with both the static and non-static properties.

It's not that bad. You can add a property to one doc that contains the other doc's ID, then declare two CBLModel classes, and declare that linking property as a pointer to the other class. The one are where it will limit what you can do, is that it makes it more difficult to create queries on both sides of the data at once.

Another option is to make the rarely-changing data an attachment (probably of type application/json.) The replicator has an optimization that allows it to skip sending attachments that haven't changed, even if the doc itself has changed.

—Jens

Steve

unread,
Sep 22, 2014, 3:44:14 PM9/22/14
to mobile-c...@googlegroups.com
Cool, thanks Jens. The ten strings are things like physical address, URL, etc, no large passages of text or anything.

Good point re attachments, worth remembering.

Steve

unread,
Sep 24, 2014, 10:31:00 AM9/24/14
to mobile-c...@googlegroups.com
I am now thinking I will retain the info in the same document (documentA), but create a second document (documentB) sort of like a detail record in a relational database. This detail record would contain all the non-critical info that rarely changes. There would be a one-to-one mapping between documentA docs and documentB docs.

How would I join the documents on the client (phone)? Is it OK to query Couchbase Lite for all the documentB docs, iterate through each of them querying Couchbase Lite using doc ID of documentA (stored in documentB)? I have 1400+ documents so this would result in 1400 queries!

I guess a better approach might be to query Couchbase Lite for all the documentB docs, then run another query for all the documentA docs whose key-value output is the doc ID and the actual document. Then iterate through each documentB doc and using the doc ID of documentA immediately pinpoint the documentA doc in the results of the second query.

Jens Alfke

unread,
Sep 24, 2014, 12:48:21 PM9/24/14
to mobile-c...@googlegroups.com

On Sep 24, 2014, at 7:31 AM, Steve <s.ande...@gmail.com> wrote:

How would I join the documents on the client (phone)? Is it OK to query Couchbase Lite for all the documentB docs, iterate through each of them querying Couchbase Lite using doc ID of documentA (stored in documentB)? I have 1400+ documents so this would result in 1400 queries!

There are a couple of tricks for this. The one that's relevant to your case, I think is this:

You can make an emitted row in the index "pretend" to come from a different document. If your map function emits a value that's a dictionary with an "_id" key, whose value is a document ID, then the resulting index row will act as though it came from that document instead. So calling CBLQueryRow.document will load the document you specified. (You can still find the actual source document via the sourceDocumentID property.)

(There are also ways to make an index merge values from multiple related documents. You design the keys so they're adjacent, then use grouping in the query to reduce those rows together. This may be overkill for your needs, though.)

—Jens
Reply all
Reply to author
Forward
0 new messages