Mongoose 21 termes

21 termes affichés

TypeBestPractice Concept Method
Niveau 🟢 Junior 🟡 Mid 🔴 Senior

Built-in Validators

Mongoose 🟢 Junior

Validateurs integres a Mongoose : required, min/max (Number), minlength/maxlength (String), enum, match (regex). Ils s'executent automatiquement avant la sauvegarde.

Un videur qui verifie ta carte d'identite, ta tenue et ta reservation avant de te laisser entrer.

{
  age: { type: Number, min: 0, max: 150 },
  role: { type: String, enum: ['user', 'admin'] },
  name: { type: String, minlength: 2 }
}

Cas d'usage : Valider les donnees utilisateur avant de les persister en base sans logique custom.

Anti-pattern : Desactiver la validation avec validateBeforeSave: false pour 'gagner en perf'.
#sgbd#interview#database#mongoose

Connection

Mongoose 🟢 Junior

Objet qui gere la connexion a MongoDB. Mongoose maintient un pool de connexions et un buffer des operations en attente jusqu'a ce que la connexion soit etablie.

Le fil du telephone entre ton appli et la base de donnees, avec une ligne d'attente integree.

await mongoose.connect(
  'mongodb://localhost:27017/mydb',
  { maxPoolSize: 10 }
);
mongoose.connection.on('error', console.error);

Cas d'usage : Initialiser la connexion a la base au demarrage de l'application NestJS ou Express.

Anti-pattern : Creer une nouvelle connexion a chaque requete HTTP au lieu de reutiliser le pool.
#sgbd#interview#database#mongoose

Custom Validators

Mongoose 🟡 Mid

Fonctions de validation personnalisees definies dans le schema. Peuvent etre synchrones ou asynchrones et retournent un booleen ou lancent une erreur.

Un test sur mesure en plus des controles standard : verifier que le code postal correspond bien a la ville.

{
  phone: {
    type: String,
    validate: {
      validator: (v) => /^\+33[0-9]{9}$/.test(v),
      message: 'Format FR invalide'
    }
  }
}

Cas d'usage : Valider des regles metier specifiques comme un format de telephone, une plage de dates ou un IBAN.

#sgbd#interview#database#mongoose

Discriminators

Mongoose 🔴 Senior

Mecanisme d'heritage de schema qui permet de stocker des documents de types differents dans une meme collection, avec un champ discriminateur (__t) pour differencier les types.

Un parking multi-vehicules : voitures, motos et camions partagent le meme espace mais ont des regles differentes.

const Event = mongoose.model('Event', eventSchema);
const Click = Event.discriminator('Click',
  new Schema({ url: String })
);
const Purchase = Event.discriminator('Purchase',
  new Schema({ amount: Number })
);

Cas d'usage : Modeliser un systeme d'evenements (analytics) ou des entites polymorphiques dans une seule collection.

#sgbd#interview#database#mongoose

Document vs Query Middleware

Mongoose 🔴 Senior

Les Document middlewares (save, validate, remove) ont this = le document. Les Query middlewares (find, update, delete) ont this = la query. Important pour savoir quoi modifier.

Document middleware = le chirurgien qui opere directement le patient. Query middleware = le pharmacien qui modifie l'ordonnance.

// Document: this = document
schema.pre('save', function() {
  console.log(this.name);
});
// Query: this = query
schema.pre('find', function() {
  this.where({ deleted: false });
});

Cas d'usage : Implementer du soft-delete en filtrant automatiquement les documents supprimes sur chaque find.

#sgbd#interview#database#mongoose

Indexes in Mongoose

Mongoose 🟡 Mid

Mongoose permet de definir les index directement dans le schema avec index: true, unique: true ou via schema.index(). Les index sont synchronises au demarrage de l'app.

Declarer les index dans le plan (schema) pour que l'architecte (MongoDB) les construise automatiquement.

userSchema.index(
  { email: 1 },
  { unique: true }
);
userSchema.index(
  { lastName: 1, firstName: 1 }
);

Cas d'usage : Gerer les index dans le code applicatif pour les versionner avec Git.

Anti-pattern : Laisser Mongoose recreer tous les index a chaque redemarrage en prod avec autoIndex: true.
#sgbd#interview#database#mongoose

lean()

Mongoose 🟡 Mid

Methode qui retourne des objets JavaScript bruts au lieu d'instances Mongoose. 2 a 5x plus rapide car elle saute l'hydratation, les getters et les virtuals.

Commander un plat a emporter sans assiette ni couverts : plus leger et plus rapide a servir.

const users = await User
  .find({ status: 'active' })
  .lean();
// users[0].save() -> Error (pas un doc Mongoose)

Cas d'usage : API en lecture seule ou les donnees sont serialisees en JSON sans modification.

Anti-pattern : Utiliser lean() puis essayer d'appeler .save() ou des methodes d'instance Mongoose.
#sgbd#interview#database#mongoose

Middleware (Pre/Post Hooks)

Mongoose 🟡 Mid

Fonctions executees avant (pre) ou apres (post) certaines operations comme save, validate, remove ou find. Permettent d'injecter de la logique transversale.

Les controles de securite a l'aeroport (pre) et le tapis a bagages (post) : ils s'executent automatiquement autour de ton vol.

userSchema.pre('save', async function() {
  if (this.isModified('password')) {
    this.password = await bcrypt.hash(
      this.password, 10
    );
  }
});

Cas d'usage : Hasher les mots de passe avant sauvegarde, logger les operations ou mettre a jour des timestamps.

Anti-pattern : Oublier d'appeler next() dans un middleware pre, bloquant toute la chaine d'execution.
#sgbd#interview#database#mongoose

Model

Mongoose 🟢 Junior

Classe construite a partir d'un Schema qui fournit l'interface CRUD pour interagir avec une collection MongoDB. Chaque instance d'un Model est un document.

Le moule a gateau (Model) cree a partir du plan (Schema) : chaque gateau (document) a la meme forme.

const User = mongoose.model('User', userSchema);
const alice = new User({ name: 'Alice' });
await alice.save();

Cas d'usage : Creer le point d'entree pour toutes les operations sur une collection dans une app Node.js.

Anti-pattern : Appeler mongoose.model() plusieurs fois avec le meme nom, causant une erreur OverwriteModelError.
#sgbd#interview#database#mongoose

Plugin

Mongoose 🟡 Mid

Fonction reutilisable qui ajoute des fonctionnalites a un schema ou a tous les schemas globalement. Permet d'encapsuler des comportements comme le soft-delete, la pagination ou l'audit.

Une extension pour navigateur : tu l'installes une fois et tous tes onglets en beneficient.

function timestampPlugin(schema) {
  schema.add({ createdAt: Date, updatedAt: Date });
  schema.pre('save', function() {
    this.updatedAt = new Date();
  });
}
mongoose.plugin(timestampPlugin);

Cas d'usage : Partager des comportements communs entre plusieurs schemas sans dupliquer le code.

#sgbd#interview#database#mongoose

populate()

Mongoose 🟡 Mid

Methode qui remplace les ObjectId references par les documents complets de la collection liee. Equivalent d'un JOIN automatique gere par Mongoose.

Cliquer sur un lien hypertexte pour voir le contenu complet au lieu de juste le numero de reference.

const order = await Order
  .findById(id)
  .populate('customer', 'name email')
  .populate('products');

Cas d'usage : Charger les donnees liees (auteur d'un article, produits d'une commande) en une seule requete logique.

Anti-pattern : Chainer plusieurs populate profonds (populate de populate) creant des dizaines de requetes.
#sgbd#interview#database#mongoose

Pre Save Hook

Mongoose 🟡 Mid

Middleware execute avant chaque appel a document.save(). Permet de modifier le document (hashing, timestamps, validation custom) avant sa persistence en base.

Le dernier controle qualite sur la chaine de montage avant de mettre le produit en boite.

schema.pre('save', function(next) {
  if (!this.slug) {
    this.slug = this.title
      .toLowerCase()
      .replace(/\s+/g, '-');
  }
  next();
});

Cas d'usage : Generer automatiquement un slug, un hash de mot de passe ou un timestamp a chaque sauvegarde.

Anti-pattern : Modifier this dans un pre save avec une arrow function, qui ne lie pas le bon this.
#sgbd#interview#database#mongoose

Query Builder

Mongoose 🟡 Mid

API chainable de Mongoose pour construire des requetes incrementalement avec where(), equals(), gt(), sort(), limit(), etc. La requete n'est executee qu'a l'appel de exec() ou await.

Un panier de courses : tu ajoutes des articles au fur et a mesure, et tu payes (exec) seulement a la fin.

const users = await User
  .where('age').gte(18)
  .where('status').equals('active')
  .sort('-createdAt')
  .limit(10)
  .exec();

Cas d'usage : Construire des requetes dynamiques en fonction des parametres de filtre d'une API.

#sgbd#interview#database#mongoose

Schema

Mongoose 🟢 Junior

Definition de la structure d'un document Mongoose : types de champs, validations, valeurs par defaut et options. Le schema est la base pour creer un Model.

Le plan d'architecte d'une maison : il definit chaque piece avant meme de poser la premiere brique.

const userSchema = new Schema({
  name: { type: String, required: true },
  email: { type: String, unique: true },
  age: { type: Number, min: 0 },
  role: { type: String, enum: ['user', 'admin'] }
});

Cas d'usage : Definir une structure stricte pour les documents MongoDB dans une application Node.js.

Anti-pattern : Definir tous les champs comme Mixed ou SchemaTypes.Mixed, perdant tout l'interet de la validation.
#sgbd#interview#database#mongoose

SchemaType Options

Mongoose 🟢 Junior

Options de configuration par champ dans un Schema : type, required, default, unique, index, lowercase, uppercase, trim, minlength, maxlength, enum, validate.

Les attributs d'un champ de formulaire HTML : requis, longueur max, format email, etc.

{
  email: {
    type: String,
    required: [true, 'Email requis'],
    lowercase: true,
    trim: true,
    match: /^\S+@\S+$/
  }
}

Cas d'usage : Definir les contraintes et transformations de chaque champ directement dans le schema.

#sgbd#interview#database#mongoose

select()

Mongoose 🟢 Junior

Methode de query qui specifie les champs a inclure ou exclure du resultat. Equivalent de la projection MongoDB mais avec une syntaxe Mongoose.

Cocher les colonnes que tu veux voir dans un tableur avant d'exporter.

const user = await User
  .findById(id)
  .select('name email -_id');

Cas d'usage : Ne retourner que les champs necessaires dans une reponse API pour reduire la bande passante.

#sgbd#interview#database#mongoose

Statics vs Methods

Mongoose 🟡 Mid

Statics sont des methodes sur le Model (niveau classe). Methods sont des methodes sur l'instance du document. Permettent d'ajouter de la logique metier au modele.

Statics = methode de classe ('User.findByEmail'). Methods = methode d'instance ('alice.comparePassword').

// Static (sur le Model)
userSchema.statics.findByEmail = function(email) {
  return this.findOne({ email });
};
// Method (sur le document)
userSchema.methods.isAdmin = function() {
  return this.role === 'admin';
};

Cas d'usage : Encapsuler la logique metier dans le modele au lieu de la disperser dans les services.

#sgbd#interview#database#mongoose

Timestamps

Mongoose 🟢 Junior

Option de schema qui ajoute automatiquement createdAt et updatedAt sur chaque document. updatedAt est mis a jour automatiquement a chaque modification.

Le tampon dateur du bureau de poste : chaque lettre recoit la date d'envoi et de reception.

const schema = new Schema(
  { name: String },
  { timestamps: true }
);
// Cree createdAt et updatedAt automatiquement

Cas d'usage : Tracer quand chaque document a ete cree et modifie pour l'audit et le debug.

#sgbd#interview#database#mongoose

toJSON / toObject Transform

Mongoose 🟡 Mid

Options de schema qui permettent de transformer la sortie JSON d'un document. Utile pour supprimer des champs sensibles ou renommer _id en id.

Un filtre photo automatique : chaque fois que tu exportes la photo, le filtre s'applique sans effort.

schema.set('toJSON', {
  virtuals: true,
  transform: (doc, ret) => {
    ret.id = ret._id;
    delete ret._id;
    delete ret.__v;
    delete ret.password;
  }
});

Cas d'usage : Formater automatiquement les reponses API en supprimant _id, __v et les champs sensibles.

#sgbd#interview#database#mongoose

Virtual Populate

Mongoose 🔴 Senior

Permet de populer une relation sans stocker de reference dans le document parent. Utilise un champ du document enfant comme foreignField pour la jointure.

Trouver tous les colis livres a une adresse sans que l'adresse ait une liste de colis.

authorSchema.virtual('books', {
  ref: 'Book',
  localField: '_id',
  foreignField: 'author'
});
await Author.findById(id).populate('books');

Cas d'usage : Creer une relation one-to-many sans tableau de references dans le parent, evitant les documents trop gros.

#sgbd#interview#database#mongoose

Virtual Properties

Mongoose 🟡 Mid

Proprietes calculees qui n'existent pas en base mais sont disponibles sur le document Mongoose. Definies via des getters et setters sur le schema.

L'age d'une personne : il n'est pas stocke, il est calcule a partir de la date de naissance.

userSchema.virtual('fullName').get(function() {
  return `${this.firstName} ${this.lastName}`;
});
const user = await User.findById(id);
console.log(user.fullName);

Cas d'usage : Creer des champs derives comme fullName, age ou un URL complete sans les stocker en base.

Anti-pattern : Oublier { toJSON: { virtuals: true } } dans le schema, les virtuals n'apparaissent pas dans les reponses API.
#sgbd#interview#database#mongoose

Autres stacks

Advanced Ecosystem Architecture CSS-in-JS DevOps HTML / CSS JavaScript MongoDB NestJS Personalities PHP PostgreSQL React Sass Styled-Components Tailwind CSS Testing TypeScript WordPress
← Retour au lexique complet