sql >> Base de Datos >  >> NoSQL >> MongoDB

¿La operación upsert de Mongoose actualiza/renueva los valores de esquema predeterminados?

Si está buscando una "prueba" del comportamiento esperado, no busque más allá del código fuente mismo. Particularmente dentro del schema.js definición principal :

        updates.$setOnInsert = {};
        updates.$setOnInsert[createdAt] = now;
      }

      return updates;
    };

    this.methods.initializeTimestamps = function() {
      if (createdAt && !this.get(createdAt)) {
        this.set(createdAt, new Date());
      }
      if (updatedAt && !this.get(updatedAt)) {
        this.set(updatedAt, new Date());
      }
      return this;
    };

    this.pre('findOneAndUpdate', _setTimestampsOnUpdate);
    this.pre('update', _setTimestampsOnUpdate);
    this.pre('updateOne', _setTimestampsOnUpdate);
    this.pre('updateMany', _setTimestampsOnUpdate);
  }

  function _setTimestampsOnUpdate(next) {
    var overwrite = this.options.overwrite;
    this.update({}, genUpdates(this.getUpdate(), overwrite), {
      overwrite: overwrite
    });
    applyTimestampsToChildren(this);
    next();
  }

Ahí puedes ver todos los 'pre' los controladores de middleware se registran para cada una de las variantes del método de "actualización" y para el mismo código funcional. Todos estos esencialmente modifican el $set operador en cualquier "actualización" que emita para incluir el updatedAt campo, o cualquier nombre que asignó a esa clave en las opciones de esquema.

La declaración real enviada con las acciones "upsert" usa $setOnInsert para el createdAt campo o nombre de la opción asignada (ver la parte superior de la lista). Esta acción solo se aplica cuando realmente se produce una "inserción superior", por lo que los documentos que existen y son simplemente coincidencias para cualquiera de los métodos de "actualización" nunca realmente afectado por este valor.

Esos operadores son parte de cómo funciona MongoDB y no tienen nada que ver con mongoose, pero el código que se muestra aquí muestra cómo mongoose "ajusta" sus acciones de "actualización" para incluir estas operaciones adicionales.

Como referencia, toda la función principal en schema.js que resuelve qué aplicar actualmente comienza en Line #798 para las genUpdates() función como se llama en la parte inferior de la lista que se muestra aquí, pero la parte superior son las últimas líneas de esa función donde están las claves de $setOnInsert definirse.

Entonces, en resumen, SÍ, cada acción de "actualización" es intencional de que updatedAt el campo asignado tiene la Date actual valor asignado, y también que las "actualizaciones" se modifican para incluir el $setOnInsert acción que solo se aplica cuando se crea un nuevo documento como resultado de una acción "upsert" para el createdAt campo asignado.