Mongoose: Basismodelle berücksichtigen Select nicht: false für Diskriminatoren

Erstellt am 16. Feb. 2017  ·  3Kommentare  ·  Quelle: Automattic/mongoose

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

confirmed-bug

Alle 3 Kommentare

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:

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen