Los captadores y definidores de Mongoose le permiten ejecutar una lógica personalizada al obtener o configurar una propiedad en un documento de Mongoose. Los captadores le permiten transformar los datos en MongoDB en una forma más fácil de usar, y los configuradores le permiten transformar los datos del usuario antes de que lleguen a MongoDB.

Getters

Suponga que tiene un User recopilación y desea ocultar los correos electrónicos de los usuarios para proteger la privacidad de sus usuarios. A continuación se muestra un básico userSchema que ofusca la dirección de correo electrónico del usuario.

const userSchema = new Schema({
  email: {
    type: String,
    get: obfuscate
  }
});

// Mongoose passes the raw value in MongoDB `email` to the getter
function obfuscate(email) {
  const separatorIndex = email.indexOf('@');
  if (separatorIndex < 3) {
    // '[email protected]' -> '**@gmail.com'
    return email.slice(0, separatorIndex).replace(/./g, '*') +
      email.slice(separatorIndex);
  }
  // '[email protected]' -> 'te****@gmail.com'
  return email.slice(0, 2) +
    email.slice(2, separatorIndex).replace(/./g, '*') +
    email.slice(separatorIndex);
}

const User = mongoose.model('User', userSchema);
const user = new User({ email: '[email protected]' });
user.email; // **@gmail.com

Tenga en cuenta que los captadores hacen no impactar los datos subyacentes almacenados en MongoDB. Si ahorras user, los email la propiedad será ‘[email protected]’en la base de datos.

De forma predeterminada, Mongoose ejecuta getters al convertir un documento a JSON, incluidos Rápido’ res.json() función.

app.get(function(req, res) {
  return User.findOne().
    // The `email` getter will run here
    then(doc => res.json(doc)).
    catch(err => res.status(500).json({ message: err.message }));
});

Para deshabilitar la ejecución de getters al convertir un documento a JSON, establezca el toJSON.getters opción a false en su esquema como se muestra a continuación.

const userSchema = new Schema({
  email: {
    type: String,
    get: obfuscate
  }
}, { toJSON: { getters: false } });

Para omitir captadores de forma única, utilice user.get() con el getters opción establecida en false Como se muestra abajo.

user.get('email', null, { getters: false }); // '[email protected]'

Setters

Suponga que desea asegurarse de que todos los correos electrónicos de los usuarios en su base de datos estén en minúsculas para facilitar la búsqueda sin preocuparse por el caso. A continuación se muestra un ejemplo userSchema que garantiza que los correos electrónicos estén en minúsculas.

const userSchema = new Schema({
  email: {
    type: String,
    set: v => v.toLowerCase()
  }
});

const User = mongoose.model('User', userSchema);

const user = new User({ email: '[email protected]' });
user.email; // '[email protected]'

// The raw value of `email` is lowercased
user.get('email', null, { getters: false }); // '[email protected]'

user.set({ email: '[email protected]' });
user.email; // '[email protected]'

Mongoose también ejecuta setters en operaciones de actualización, como updateOne(). La mangosta insertar un documento con minúsculas email en el siguiente ejemplo.

await User.updateOne({}, { email: '[email protected]' }, { upsert: true });

const doc = await User.findOne();
doc.email; // '[email protected]'

En una función de setter, this puede ser el documento que se está configurando o la consulta que se está ejecutando. Si no quiere que su setter se ejecute cuando llame updateOne(), agrega una declaración if que verifica si this es un documento de Mongoose como se muestra a continuación.

const userSchema = new Schema({
  email: {
    type: String,
    set: toLower
  }
});

function toLower(email) {
  // Don't transform `email` if using `updateOne()` or `updateMany()`
  if (!(this instanceof mongoose.Document)) {
    return email;
  }
  return email.toLowerCase();
}

const User = mongoose.model('User', userSchema);
await User.updateOne({}, { email: '[email protected]' }, { upsert: true });

const doc = await User.findOne();
doc.email; // '[email protected]'

Diferencias vs Getters / Setters ES6

Los setters de mangostas son diferentes de Incubadoras ES6 porque te permiten transformar el valor que se establece. Con las incubadoras ES6, necesitaría almacenar una _email propiedad para usar un setter. Con Mongoose, lo haces no Necesito definir un interno _email propiedad o definir un captador correspondiente para email.

class User {
  // This won't convert the email to lowercase! That's because `email`
  // is just a setter, the actual `email` property doesn't store any data.
  set email(v) {
    return v.toLowerCase();
  }
}

const user = new User();
user.email = '[email protected]';

user.email; // undefined