Mongoose: Model dasar tidak menghormati pilih: salah untuk diskriminator

Dibuat pada 16 Feb 2017  ·  3Komentar  ·  Sumber: Automattic/mongoose

Apakah Anda ingin meminta fitur atau melaporkan bug ?
Serangga

Apa perilaku saat ini?
Ketika model dasar digunakan untuk mengambil dokumen model diskriminator, itu tidak menghormati select: false .

Jika perilaku saat ini adalah bug, berikan langkah-langkah untuk mereproduksi.

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 };
}

Apa perilaku yang diharapkan?
Kita mungkin harus membatalkan pilihan bidang tersebut secara manual setelah mengambil dari database, karena luwak tidak tahu sebelumnya diskriminator mana yang harus dipilih.

Sebutkan versi node.js, luwak, dan MongoDB Anda.
simpul 6.9.2, luwak 4.8.3, mongodb 3.4

confirmed-bug

Semua 3 komentar

Sepertinya saya mengalami efek samping yang tidak terduga dari perubahan ini:

Saya memiliki model dasar A , dengan model diskriminator B .
Ketika saya meminta A untuk dokumen menggunakan proyeksi array $slice , dokumen yang dihasilkan bertipe A mengembalikan semua properti (tidak termasuk yang ditandai sebagai select: false ), sementara menghasilkan dokumen bertipe B hanya mengembalikan properti _eksplisit_ yang ditandai sebagai select: true atau properti dengan set default . Mereka yang memiliki set default mengembalikan nilai default, bukan nilai yang sebenarnya disimpan dalam database. Jika tidak ada properti yang ditandai dengan select: true , hanya properti dengan nilai default yang dikembalikan (sekali lagi dengan nilai default, bukan nilai toko).

EDIT : Abaikan komentar saya, masalahnya adalah luwak menambahkan kunci diskriminator ke kueri di bawah tenda. Solusinya adalah menggunakan fungsi slice pada Query.

Saya mungkin berbicara terlalu cepat. Pengujian dengan kedua versi 4.13.4 dan komit master , saya melihat perilaku yang sama ketika hanya menggunakan proyeksi slice .

Saya telah mengambil contoh asli dalam masalah ini dan memodifikasi untuk mereproduksi perilaku:

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 };
}

Perilaku ini berubah di 4.11.13 , itulah sebabnya saya menduga resolusi untuk masalah ini sebagai penyebabnya. Jika tidak, saya akan dengan senang hati membuat edisi baru

Terima kasih telah melaporkan @bruun , akan segera diselidiki :+1:

Apakah halaman ini membantu?
0 / 5 - 0 peringkat