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
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: