NodeJS Mongoose中缺少的值在将对象列表Map到字符串列表时进行预验证

esyap4oy  于 2023-06-29  发布在  Node.js
关注(0)|答案(1)|浏览(109)

我正在尝试使用请求正文中的数据创建新记录。请求主体数据如下所示:

{
  extras: [{value: "string"}, {value: "string"}, {value: "string"}],
  skills: [{value: "string"}, {value: "string"}]
}

这些特性包含对象列表。为了在post请求处理程序中创建一条新记录,我使用以下代码:

const record = new Record(req.body);
try {
  const newRecord = await record.save();
  res.status(200).json(newRecord);
} catch (err) {
  res.status(400).json({ message: err.message });
}

但是,我的Mongoose模式希望这些属性是字符串列表。为了在将记录保存到数据库之前将对象值转换为字符串,我添加了一个pre-validate钩子。下面是我的代码:

const recordSchema = new Schema(
  {
    extras: [String],
    skills: [String]
  },
  {
    timestamps: true
  }
)

recordSchema.pre('validate', function (next) {
  console.log(this);
  this.extras = this.extras.map(v => v.value);
  this.skills = this.skills.map(v => v.value);
  return next();
});

当我在pre-validate钩子中记录这个时,我看到缺少值:

{
  extras: [],
  skills: []
}

在保存记录之前,如何确保值正确地从对象Map到字符串?

hgncfbus

hgncfbus1#

架构中不存在的任何键/瓦尔集总是被忽略。
[{value: 'string'}]与架构中的extras键不匹配,将被忽略。

import mongoose from 'mongoose';
import { config } from '../../config';

mongoose.set('debug', true);

const recordSchema = new mongoose.Schema({
    extras: [String],
    skills: [String],
});
recordSchema.pre('validate', function (next) {
    console.log('this: ', this);
    next();
});
const Record = mongoose.model('record', recordSchema);

(async function main() {
    try {
        await mongoose.connect(config.MONGODB_URI);
        await Promise.all([Record].map((m) => m.collection.drop()));
        // seed
        const body = {
            extras: [{ value: 'a' }, { value: 'b' }, { value: 'c' }],
            skills: [{ value: 'x' }, { value: 'y' }],
        };
        const r1 = new Record(body);
        console.log('r1: ', r1);

        const r2 = new Record({ extras: body.extras.map((v) => v.value), skills: body.skills.map((v) => v.value) });
        console.log('r2: ', r2);
        await r2.save();
    } catch (error) {
        console.error(error);
    } finally {
        await mongoose.connection.close();
    }
})();

调试日志:

r1:  {
  extras: [],
  skills: [],
  _id: new ObjectId("6499913304a2e6257b3b5186")
}
r2:  {
  extras: [ 'a', 'b', 'c' ],
  skills: [ 'x', 'y' ],
  _id: new ObjectId("6499913304a2e6257b3b5187")
}
this:  {
  extras: [ 'a', 'b', 'c' ],
  skills: [ 'x', 'y' ],
  _id: new ObjectId("6499913304a2e6257b3b5187")
}
Mongoose: records.insertOne({ extras: [ 'a', 'b', 'c' ], skills: [ 'x', 'y' ], _id: ObjectId("6499913304a2e6257b3b5187"), __v: 0}, {})

比较r1文档和r2文档。你不能在pre('validate')中间件中转换/处理无效的键/值,因为mongoose会忽略它们。因此,尝试处理req.body以匹配模式中的键/值,并使用proceed数据创建模型示例。

相关问题