À partir de Mongoose 4+, n'oubliez pas de définir new :true avec upsert ou vous obtiendrez l'ancien document comme valeur de retour, pas celui mis à jour.
C'est assez délicat surtout lorsque la requête crée un document, comme si vous ne spécifiiez pas new :true, vous recevez un document nul (il n'y avait pas de doc existant), mais pas d'erreur.
var myObj = ...;
collection.findOneAndUpdate(
{uniqueAttr: myObj.uniqueAttr},
myObj,
{upsert: true, new: true},
function(...) {...}