Vous souhaitez demander une fonctionnalité ou signaler un bug ?
Bogue
Quel est le comportement actuel ?
Lorsqu'un modèle de base est utilisé pour récupérer un document de modèle discriminateur, il n'honore pas select: false
.
Si le comportement actuel est un bogue, veuillez fournir les étapes à reproduire.
const mongoose = require('mongoose');
mongoose.Promise = global.Promise;
const co = require('co');
const chalk = require('chalk');
const GITHUB_ISSUE = `test-constructor-emit-bug`;
exec()
.then(() => {
console.log(chalk.green(`Successfully ran program`));
process.exit(0);
})
.catch(error => {
console.log(chalk.red(`Error: ${ error }\n${ error.stack }`));
process.exit(2);
});
function exec() {
return co(function* () {
const db = mongoose.createConnection(`mongodb://localhost:27017/${ GITHUB_ISSUE }`);
const { Base, Discriminator } = createModels(db);
const { baseDoc, discrimDoc } = yield seedDb({ Base, Discriminator });
const docFromDb = yield Base.findById(discrimDoc._id) // does not honor select: false
// const docFromDb = yield Discriminator.findById(discrimDoc._id); // honors select: false
console.log(docFromDb.internal); // should not log `internal.password`
});
}
function seedDb(models) {
return co(function*() {
const { Base, Discriminator } = models;
yield [Base.remove({}), Discriminator.remove({})];
const baseDoc = yield Base.create({ internal: { diseases: ['Malaria'] }});
const discrimDoc = yield Discriminator.create({ internal: {
diseases: ['MS'],
password: 'plain_test_password_ftw'
}});
return { baseDoc, discrimDoc };
});
}
function createModels(db) {
const baseSchema = new mongoose.Schema({
internal: {
diseases: [{ type: String }]
}
});
const Base = db.model('Base', baseSchema);
const discriminatorSchema = new mongoose.Schema({
internal: {
password: { type: String, select: false }
}
});
const Discriminator = Base.discriminator('Discriminator', discriminatorSchema);
return { Base, Discriminator };
}
Quel est le comportement attendu ?
Nous devrions probablement désélectionner ces champs manuellement après l'extraction de la base de données, car la mangouste ne sait pas à l'avance pour quels discriminateurs sélectionner.
Veuillez mentionner votre version node.js, mongoose et MongoDB.
nœud 6.9.2, mangouste 4.8.3, mongodb 3.4
Il semble que je ressente des effets secondaires inattendus suite à ce changement :
J'ai un modèle de base A
, avec un modèle discriminateur B
.
Lorsque j'interroge A pour des documents à l'aide d'une projection de tableau $slice
, les documents résultants de type A
renvoient toutes les propriétés (à l'exception de celles marquées comme select: false
), tandis que les documents résultants de type B
ne renvoient que les propriétés _explicitement_ marquées comme select: true
ou celles avec un ensemble default
. Ceux avec un ensemble default
renvoient la valeur par défaut, pas la valeur réellement stockée dans la base de données. Si aucune propriété n'est marquée avec select: true
, seules les propriétés avec des valeurs default
sont renvoyées (là encore avec la valeur par défaut, pas la valeur de stockage).
EDIT : Ne tenez pas compte de mon commentaire, le problème était que la mangouste ajoute la clé discriminante à la requête sous le capot. La solution consistait à utiliser la fonction slice
sur la requête.
J'ai peut-être parlé trop tôt. En testant à la fois la version 4.13.4 et le dernier commit master
, je constate le même comportement lorsque je n'utilise que la projection slice
.
J'ai pris l'exemple d'origine dans ce numéro et modifié pour reproduire le comportement :
const mongoose = require('mongoose');
mongoose.Promise = global.Promise;
const co = require('co');
const chalk = require('chalk');
mongoose.set('debug', true);
const GITHUB_ISSUE = `default-values-on-discriminator-documents`;
exec()
.then(() => {
console.log(chalk.green(`Successfully ran program`));
process.exit(0);
})
.catch(error => {
console.log(chalk.red(`Error: ${error}\n${error.stack}`));
process.exit(2);
});
function exec() {
return co(function* () {
const db = mongoose.createConnection(`mongodb://localhost:27017/${GITHUB_ISSUE}`);
const { Base, Discriminator } = createModels(db);
const { baseDoc, discrimDoc } = yield seedDb({ Base, Discriminator });
const baseDocsFromDbWithSlice = yield Base.find().slice('array', 1)
const baseDocsFromDb = yield Base.find()
console.log(baseDocsFromDbWithSlice); // Discriminator document returns default value for propA (and not propB), base document returns stored value - unexpected
console.log(baseDocsFromDb); // Discriminator and base document returns stored value for propA - expected
});
}
function seedDb(models) {
return co(function* () {
const { Base, Discriminator } = models;
yield [Base.remove({}), Discriminator.remove({})];
const baseDoc = yield Base.create({
propA: 'Hi',
array: ["a", "b"]
});
const discrimDoc = yield Discriminator.create({
propA: 'Hi',
propB: 'Hello',
array: ["a", "b"]
});
return { baseDoc, discrimDoc };
});
}
function createModels(db) {
const baseSchema = new mongoose.Schema({
propA: { type: String, default: 'default value' },
array: [{type: String}],
});
const Base = db.model('Base', baseSchema);
const discriminatorSchema = new mongoose.Schema({
propB: { type: String}
});
const Discriminator = Base.discriminator('Discriminator', discriminatorSchema);
return { Base, Discriminator };
}
Ce comportement a changé dans 4.11.13
, c'est pourquoi je soupçonnais que la résolution de ce problème en était la cause. Sinon, je serai heureux de créer un nouveau problème
Merci d'avoir signalé @bruun , enquêtera dès que possible :+1 :