I believe that our documentation on $set should include a section which explains how it doesn't change the fields that don't change in the update, so only ones that changed get written to the oplog. This is a major selling point for using $set and, in my point of view, not obvious that it works like that.
Advantages over full document replacement:
- Computes the delta of the existing document and fields in $set
- Only changes are written to the oplog
- Smaller memory footprint
This saves a lot of work for the client intersecting documents to figure out which fields have been changed before sending an update.