MongoDB
 sql >> Base de Dados >  >> NoSQL >> MongoDB

A operação de upsert do Mongoose atualiza/renova os valores de esquema padrão?


Se você estiver procurando por "prova" do comportamento esperado, não procure mais do que o próprio código-fonte. Particularmente no schema.js definição 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();
  }

Então lá você pode ver todos os 'pre' manipuladores de middleware sendo registrados para cada uma das variantes do método "update" e para o mesmo código funcional. Todos eles basicamente modificam o $set operador em qualquer "atualização" que você emitir para incluir o updatedAt campo, ou qualquer nome que você mapeou para essa chave nas opções de esquema.

A declaração real enviada com ações "upsert" usa $setOnInsert para o createdAt campo ou nome da opção mapeada (veja o topo da lista). Esta ação somente se aplica quando um "upsert" realmente ocorre, portanto, documentos que existem e são apenas correspondências para qualquer um dos métodos de "atualização" nunca realmente tocado por este valor.

Esses operadores fazem parte de como o MongoDB funciona e não tem a ver com o mongoose, mas o código mostrado aqui mostra como o mongoose "ajusta" suas ações de "atualização" para incluir essas operações adicionais.

Para referência de toda a função principal em schema.js que determina o que aplicar atualmente começa em Linha 798 para o genUpdates() função como chamada na parte inferior da lista mostrada aqui, mas a parte superior são as últimas linhas dessa função, onde as teclas de $setOnInsert se defina.

Então, em resumo, sim, toda ação de "atualização" é intencional que o updatedAt campo mapeado tem a Data atual valor atribuído e também que as "atualizações" sejam modificadas para incluir o $setOnInsert ação que somente se aplica quando um novo documento é criado como resultado de uma ação "upsert" para o createdAt campo mapeado.