function _update(query, op, conditions, doc, options, callback) {
  // make sure we don't send in the whole Document to merge()
  query.op = op;
  conditions = utils.toObject(conditions);

  var oldCb = callback;
  if (oldCb) {
    if (typeof oldCb === 'function') {
      callback = function(error, result) {
        oldCb(error, result ? result.result : {ok: 0, n: 0, nModified: 0});
      };
    } else {
      throw new Error('Invalid callback() argument.');
    }
  }

  // strict is an option used in the update checking, make sure it gets set
  if (options) {
    if ('strict' in options) {
      query._mongooseOptions.strict = options.strict;
    }
  }

  // if doc is undefined at this point, this means this function is being
  // executed by exec(not always see below). Grab the update doc from here in
  // order to validate
  // This could also be somebody calling update() or update({}). Probably not a
  // common use case, check for _update to make sure we don't do anything bad
  if (!doc && query._update) {
    doc = query._updateForExec();
  }

  if (mquery.canMerge(conditions)) {
    query.merge(conditions);
  }

  // validate the selector part of the query
  var castedQuery = castQuery(query);
  if (castedQuery instanceof Error) {
    query._castError = castedQuery;
    if (callback) {
      callback(castedQuery);
      return query;
    } else if (!options || !options.dontThrowCastError) {
      throw castedQuery;
    }
  }

  // validate the update part of the query
  var castedDoc;
  try {
    var $options = {retainKeyOrder: true};
    if (options && options.minimize) {
      $options.minimize = true;
    }
    castedDoc = query._castUpdate(utils.clone(doc, $options),
      (options && options.overwrite) || op === 'replaceOne');
  } catch (err) {
    query._castError = castedQuery;
    if (callback) {
      callback(err);
      return query;
    } else if (!options || !options.dontThrowCastError) {
      throw err;
    }
  }

  castedDoc = setDefaultsOnInsert(query, query.schema, castedDoc, options);
  if (!castedDoc) {
    // Make sure promises know that this is still an update, see gh-2796
    query.op = op;
    callback && callback(null);
    return query;
  }

  if (utils.isObject(options)) {
    query.setOptions(options);
  }

  if (!query._update) {
    query._update = castedDoc;
  }

  // Hooks
  if (callback) {
    if (op === 'update') {
      return query._execUpdate(callback);
    }
    return query['_' + op](callback);
  }

  return Query.base[op].call(query, castedQuery, castedDoc, options, callback);
}
/*!
 * Internal helper for update, updateMany, updateOne, replaceOne
 */
Internal helper for update, updateMany, updateOne, replaceOne
Internal helper for update updateMany updateOne replaceOne
function _update(query, op, conditions, doc, options, callback) {
  query.op = op;
  conditions = utils.toObject(conditions);
  var oldCb = callback;
  if (oldCb) {
    if (typeof oldCb === 'function') {
      callback = function(error, result) {
        oldCb(error, result ? result.result : {ok: 0, n: 0, nModified: 0});
      };
    } else {
      throw new Error('Invalid callback() argument.');
    }
  }
  if (options) {
    if ('strict' in options) {
      query._mongooseOptions.strict = options.strict;
    }
  }
  if (!doc && query._update) {
    doc = query._updateForExec();
  }
  if (mquery.canMerge(conditions)) {
    query.merge(conditions);
  }
  var castedQuery = castQuery(query);
  if (castedQuery instanceof Error) {
    query._castError = castedQuery;
    if (callback) {
      callback(castedQuery);
      return query;
    } else if (!options || !options.dontThrowCastError) {
      throw castedQuery;
    }
  }
  var castedDoc;
  try {
    var $options = {retainKeyOrder: true};
    if (options && options.minimize) {
      $options.minimize = true;
    }
    castedDoc = query._castUpdate(utils.clone(doc, $options),
      (options && options.overwrite) || op === 'replaceOne');
  } catch (err) {
    query._castError = castedQuery;
    if (callback) {
      callback(err);
      return query;
    } else if (!options || !options.dontThrowCastError) {
      throw err;
    }
  }
  castedDoc = setDefaultsOnInsert(query, query.schema, castedDoc, options);
  if (!castedDoc) {
    query.op = op;
    callback && callback(null);
    return query;
  }
  if (utils.isObject(options)) {
    query.setOptions(options);
  }
  if (!query._update) {
    query._update = castedDoc;
  }
  if (callback) {
    if (op === 'update') {
      return query._execUpdate(callback);
    }
    return query['_' + op](callback);
  }
  return Query.base[op].call(query, castedQuery, castedDoc, options, callback);
}
function _update ( query , op , conditions , doc , options , callback ) { query . op = op ; conditions = utils . toObject ( conditions ) ; var oldCb = callback ; if ( oldCb ) { if ( typeof oldCb === 'function' ) { callback = function ( error , result ) { oldCb ( error , result ? result . result : { ok : 0 , n : 0 , nModified : 0 } ) ; } ; } else { throw new Error ( 'Invalid callback() argument.' ) ; } } if ( options ) { if ( 'strict' in options ) { query . _mongooseOptions . strict = options . strict ; } } if ( ! doc && query . _update ) { doc = query . _updateForExec ( ) ; } if ( mquery . canMerge ( conditions ) ) { query . merge ( conditions ) ; } var castedQuery = castQuery ( query ) ; if ( castedQuery instanceof Error ) { query . _castError = castedQuery ; if ( callback ) { callback ( castedQuery ) ; return query ; } else if ( ! options || ! options . dontThrowCastError ) { throw castedQuery ; } } var castedDoc ; try { var $options = { retainKeyOrder : true } ; if ( options && options . minimize ) { $options . minimize = true ; } castedDoc = query . _castUpdate ( utils . clone ( doc , $options ) , ( options && options . overwrite ) || op === 'replaceOne' ) ; } catch ( err ) { query . _castError = castedQuery ; if ( callback ) { callback ( err ) ; return query ; } else if ( ! options || ! options . dontThrowCastError ) { throw err ; } } castedDoc = setDefaultsOnInsert ( query , query . schema , castedDoc , options ) ; if ( ! castedDoc ) { query . op = op ; callback && callback ( null ) ; return query ; } if ( utils . isObject ( options ) ) { query . setOptions ( options ) ; } if ( ! query . _update ) { query . _update = castedDoc ; } if ( callback ) { if ( op === 'update' ) { return query . _execUpdate ( callback ) ; } return query [ '_' + op ] ( callback ) ; } return Query . base [ op ] . call ( query , castedQuery , castedDoc , options , callback ) ; }
Internal helper for update, updateMany, updateOne, replaceOne
Internal helper for update updateMany updateOne replaceOne
// make sure we don't send in the whole Document to merge() // strict is an option used in the update checking, make sure it gets set // if doc is undefined at this point, this means this function is being // executed by exec(not always see below). Grab the update doc from here in // order to validate // This could also be somebody calling update() or update({}). Probably not a // common use case, check for _update to make sure we don't do anything bad // validate the selector part of the query // validate the update part of the query // Make sure promises know that this is still an update, see gh-2796 // Hooks