I understand the confusion, a document mutates in Couchbase if there is a change to either it’s body or it’s meta data (TTL and other XATTRS). I believe this is an artifact of our Database Change Protocol (or DCP). Imagine the problems if a document was updated (say the TTL) and it wasn’t put at the end of the DCP stream you would get inconsistencies in your data when all the changes were replayed form the beginning of time.
Now for you issue at hand you can use the crc64() built-in function to determine if the document actually changed we discuss this in the Eventing documents to suppress duplicate mutations form our Sync Gateway product (which updates XATTRs domeitmes without altering the document). Refer to Language Constructs | Couchbase Docs for details.
The crc64() built-in function can also be used to determine if a subset of a document has changed refer to Function: convertXMLtoJSON | Couchbase Docs for an example on who to avoid a CPU intensive recalculation if a portion of the document hasn’t changed.
I do want to point out that you appear to be using N1QL (either in-line or via the N1QL() built-in function), if you update the source bucket of the Eventing mutations you can trigger infinite recursion in your eventing function if you are not careful. Note this “recursion” is automatically suppressed if you use a bucket binding or alias for your source bucket update via KV.
As a simple example you could perform the following if your “potential” changes were entirely within Eventing:
if (doc.type !== "doc_type_to_process" ) return; // ignore items that we don't care about.
var crc1 = crc64(doc); // save a checksum
// do a lot of work on the document
var crc2 = crc64(doc); // save a second checksum
if (crc1 === crc2) return; // no change in the "doc" just return
// the doc is different so update it in KV via a bucket binding alias, in this case "src_bkt"
src_bkt[meta.id] = doc;
Obviously the above is a toy where the updates all happen in the Eventing handler and might not fit your use case - but I have to ask, why are you using a document that doesn’t change in the first place. ou could apply the same principle in an SDK or perhaps even N1Ql in the query workbench.