Mongoose: 基本模型不支持 select: false 鉴别器

创建于 2017-02-16  ·  3评论  ·  资料来源: Automattic/mongoose

您要请求功能还是报告错误
漏洞

目前的行为是什么?
当基本模型用于检索鉴别器模型文档时,它不支持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

confirmed-bug

所有3条评论

我似乎正在经历这种变化带来的意想不到的副作用:

我有一个基本模型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:

此页面是否有帮助?
0 / 5 - 0 等级