您要请求功能还是报告错误?
漏洞
目前的行为是什么?
当基本模型用于检索鉴别器模型文档时,它不支持select: false
。
如果当前行为是错误,请提供重现步骤。
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 };
}
什么是预期行为?
我们可能应该在从数据库中获取后手动取消选择这些字段,因为 mongoose 不知道要选择哪些鉴别器。
请提及您的 node.js、mongoose 和 MongoDB 版本。
节点 6.9.2、猫鼬 4.8.3、mongodb 3.4
我似乎正在经历这种变化带来的意想不到的副作用:
我有一个基本模型A
,带有一个鉴别器模型B
。
当我使用$slice
数组投影查询文档 A 时,生成的A
类型的文档返回所有属性(不包括标记为select: false
属性),而生成的B
类型的文档select: true
或具有default
集的属性。 具有default
集的那些返回默认值,而不是实际存储在数据库中的值。 如果没有用select: true
标记的属性,则只返回具有default
值的属性(同样使用默认值,而不是商店值)。
编辑:忽略我的评论,问题是猫鼬在后台将鉴别器键添加到查询中。 解决方案是在查询上使用slice
函数。
我可能说得太早了。 使用版本 4.13.4 和最新的master
提交进行测试,我在仅使用slice
投影时看到相同的行为。
我在这个问题中采用了原始示例并进行了修改以重现该行为:
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 };
}
这种行为在4.11.13
,这就是为什么我怀疑此问题的解决方案是原因。 如果没有,我很乐意创建一个新问题
感谢您报告@bruun ,将尽快调查:+1: