Sync function... how do I update doc1 when doc2 is inserted?

Suppose this is already in the bucket:

Author1
{
  "Name": "Bill Shakespeare",
  "Books": "11"
}

Now I insert:

Book47
{
  "Title": "Othello",
  "AuthorID": "Author1"
}

Is there a way to Author1.Books++ in the sync function when Book47 is inserted?

If not, then how can I accomplish this? changes listener?

Kind regards,
David

No, it’s not possible for the sync function to modify documents (even the incoming document).

There are a few different approaches you might take for the example scenario you mentioned. I think the most common approach would be to use views to perform aggregation operations like count - either in Couchbase Lite or in Couchbase Server.

If you’re looking for a more complex update operation that’s not suited to views, and also can’t be implemented in your client application, then the changes worker pattern might be your best bet, as you suggest. If you haven’t already seen it, there’s some documentation on that topic here:
http://developer.couchbase.com/mobile/develop/guides/sync-gateway/changes-worker/pattern/index.html

Thanks @adamf!

So, my options for AuthorX.Books are:

  1. Use a count view every time I want to know how many books are associated with AuthorX
  • this requires couchbase to actually do the math on every read request which is an ongoing hit on performance (not a big deal for count, but if it’s a function with more complicated math, this could be significant)
  • but we know the count is accurate (there’s no chance of deleting BookY and forgetting to update AuthorX.Books)
  1. Use “Changes Worker Pattern

  2. Use “Webhooks

  • “Prior to the 1.1 release, the only way to add custom logic in the form of plugins to Sync Gateway was to listen on the changes feed. While this approach still works, it isn’t the easiest to setup. With webhooks, you can simply provide a filter function and the URL to post the event to. Then, you handle the event with the back-end language of your choice (NodeJS, Java, Go, Ruby…).”

I think Webhooks is the way to go. By filtering “changes” you only spend CPU operation on the ones you care about.

Kind regards,
David

What if I want to validate the document based on other documents stored in bucket and reject in sync function? I cant do in webhook or other thing because by then the original document will already be stored.

How did you solve this in the end? We’re looking from something similar

@avia_tm When doc is inserted, you can have the script on server side to listen to doc changes and update or act based on those changes using admin port.

I would not directly feed off the admin port. Instead can create a user like below.
HTTP/PUT :4985/{db}/_user

{ "name":"backend_process1", "password":"super-hush-hush", "admin_roles":["editor"], "admin_channels":["authors"] }

so in the above you still have to go through the data port in SG.
and in your sync function just make it so that when the doc comes is just put it in the channel.

channel("authors");