Zestaw $ operator jest używany na upsert także. Więc nonsensem jest odwoływanie się do tych samych pól w zestawie $ i $setOnInsert .
Po prostu wypróbuj to na pustej kolekcji:
db.items.remove();
db.items.update({},{$set:{a:1},$setOnInsert:{b:2}},{upsert:1})
db.items.find({});