Möchten Sie eine Funktion anfordern oder einen Fehler melden?
Insekt
Wie ist das aktuelle Verhalten?
Wenn ein Basismodell verwendet wird, um ein Diskriminatormodelldokument abzurufen, wird select: false
nicht berücksichtigt.
Wenn das aktuelle Verhalten ein Fehler ist, geben Sie bitte die Schritte zum Reproduzieren an.
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 };
}
Was ist das erwartete Verhalten?
Wir sollten diese Felder nach dem Abrufen aus der Datenbank wahrscheinlich manuell abwählen, da Mungo im Voraus nicht weiß, für welche Diskriminatoren sie auswählen sollen.
Bitte erwähnen Sie Ihre node.js-, Mongoose- und MongoDB-Version.
Knoten 6.9.2, Mungo 4.8.3, Mongodb 3.4
Ich scheine unerwartete Nebenwirkungen dieser Änderung zu haben:
Ich habe ein Basismodell A
, mit einem Diskriminatormodell B
.
Wenn ich A nach Dokumenten mit einer $slice
Arrayprojektion abfrage, geben resultierende Dokumente vom Typ A
alle Eigenschaften zurück (außer denen, die als select: false
), während resultierende Dokumente vom Typ B
nur Eigenschaften zurück, die _explizit_ als select: true
markiert sind, oder solche mit einem default
Satz. Diejenigen mit einem default
Satz geben den Standardwert zurück, nicht den tatsächlich in der Datenbank gespeicherten Wert. Wenn keine Eigenschaften mit select: true
markiert sind, werden nur Eigenschaften mit default
Werten zurückgegeben (wieder mit dem Standardwert, nicht dem Store-Wert).
BEARBEITEN : Ignorieren Sie meinen Kommentar, das Problem war, dass Mungo der Abfrage unter der Haube den Diskriminatorschlüssel hinzufügt. Die Lösung bestand darin, die Funktion slice
für die Abfrage zu verwenden.
Ich habe vielleicht zu früh gesprochen. Beim Testen mit Version 4.13.4 und dem neuesten master
Commit sehe ich das gleiche Verhalten, wenn ich nur die slice
Projektion verwende.
Ich habe das ursprüngliche Beispiel in dieser Ausgabe genommen und modifiziert, um das Verhalten zu reproduzieren:
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 };
}
Dieses Verhalten hat sich in 4.11.13
geändert, weshalb ich vermutete, dass die Lösung für dieses Problem die Ursache ist. Wenn nicht, erstelle ich gerne eine neue Ausgabe
Vielen Dank, dass Sie @bruun gemeldet schnell wie möglich untersuchen :+1: