Postman向MongoDB提交数据遇ObjectId转换错误求助
解决MongoDB/Mongoose的_id类型转换错误
使用Postman通过http://localhost:5000/api/import/products接口提交产品数据时触发ValidationError,错误信息如下:
{ "message": "Product validation failed: _id: Cast to ObjectId failed for value \"1\" (type string) at path \"_id\"", "stack": "ValidationError: Product validation failed: _id: Cast to ObjectId failed for value \"1\" (type string) at path \"_id\"\n at model.Document.invalidate (D:\\Uni\\SE_Y3\\Semester 1\\Web Programming\\Project code\\Uptown_Book\\server\\node_modules\\mongoose\\lib\\document.js:2917:32)\n at model.$set (D:\\Uni\\SE_Y3\\Semester 1\\Web Programming\\Project code\\Uptown_Book\\server\\node_modules\\mongoose\\lib\\document.js:1454:12)\n at model.$set (D:\\Uni\\SE_Y3\\Semester 1\\Web Programming\\Project code\\Uptown_Book\\server\\node_modules\\mongoose\\lib\\document.js:1149:16)\n at model.Document (D:\\Uni\\SE_Y3\\Semester 1\\Web Programming\\Project code\\Uptown_Book\\server\\node_modules\\mongoose\\lib\\document.js:158:12)\n at model.Model (D:\\Uni\\SE_Y3\\Semester 1\\Web Programming\\Project code\\Uptown_Book\\server\\node_modules\\mongoose\\lib\\model.js:107:12)\n at new model (D:\\Uni\\SE_Y3\\Semester 1\\Web Programming\\Project code\\Uptown_Book\\server\\node_modules\\mongoose\\lib\\model.js:4792:15)\n at Array.<anonymous> (D:\\Uni\\SE_Y3\\Semester 1\\Web Programming\\Project code\\Uptown_Book\\server\\node_modules\\mongoose\\lib\\model.js:3336:17)\n at _start (D:\\Uni\\SE_Y3\\Semester 1\\Web Programming\\Project code\\Uptown_Book\\server\\node_modules\\mongoose\\lib\\helpers\\parallelLimit.js:27:37)\n at parallelLimit (D:\\Uni\\SE_Y3\\Semester 1\\Web Programming\\Project code\\Uptown_Book\\server\\node_modules\\mongoose\\lib\\helpers\\parallelLimit.js:23:5)\n at Function.Model.$__insertMany (D:\\Uni\\SE_Y3\\Semester 1\\Web Programming\\Project code\\Uptown_Book\\server\\node_modules\\mongoose\\lib\\model.js:3366:3)" }
提交的产品数据:
const products = [ { _id: "1", name: "Velcro Ballerinas For Girls (Pink)", image: "/images/6.png", description: "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book", price: 89, countInStock: 3, rating: 4, numReviews: 4, }, { _id: "2", name: "Velcro Sneakers For Boys & Girls (Blue)", image: "/images/5.png", description: "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book", price: 599, countInStock: 10, rating: 2, numReviews: 2, }, { _id: "3", name: "Sesame Street Unisex-Child ELMO Puppet Slipper", image: "/images/4.png", description: "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book", price: 929, countInStock: 0, rating: 3.5, numReviews: 3, }, { _id: "4", name: "Lace Casual Boots For Boys & Girls (Tan)", image: "/images/3.png", description: "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book", price: 399, countInStock: 10, rating: 5, numReviews: 9, }, { _id: "5", name: "Lace Walking Shoes For Boys & Girls (Pink)", image: "/images/2.png", description: "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book", price: 49, countInStock: 7, rating: 2, numReviews: 2, }, { _id: "6", name: "Women Red Heels Sandal", image: "/images/1.png", description: "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book", price: 29, countInStock: 0, rating: 0, numReviews: 0, }, ]; export default products;
修复方案
方案1:移除自定义_id,让Mongo自动生成
Mongoose默认会为每个文档自动生成符合ObjectId格式的_id,无需手动指定数值型字符串的_id。修改产品数据,删除所有_id字段即可:
const products = [ { name: "Velcro Ballerinas For Girls (Pink)", image: "/images/6.png", description: "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book", price: 89, countInStock: 3, rating: 4, numReviews: 4, }, // 其他产品同理,删除_id字段 ];
方案2:修改Schema,允许自定义字符串类型的_id
如果必须使用自定义的_id(如数值字符串"1"、"2"),需在Mongoose的Product Schema中显式指定_id类型为String,而非默认的ObjectId:
const productSchema = new mongoose.Schema({ _id: { type: String, required: true }, // 指定类型为String name: { type: String, required: true }, image: { type: String, required: true }, description: { type: String, required: true }, price: { type: Number, required: true }, countInStock: { type: Number, required: true }, rating: { type: Number, required: true }, numReviews: { type: Number, required: true }, }); const Product = mongoose.model('Product', productSchema);
修改Schema后重启服务,再提交原数据即可通过验证。
方案3:将_id转换为ObjectId格式(不推荐,除非有特殊需求)
若坚持使用ObjectId类型的_id,需把每个产品的_id改成MongoDB认可的24位十六进制ObjectId字符串,例如:
const products = [ { _id: "60d21b4667d0d8992e610c85", // 合法的ObjectId // 其他字段不变 }, ];
此方式需手动生成合法的ObjectId,一般不建议,除非有特定关联需求。
内容的提问来源于stack exchange,提问作者Shiraie
相关产品推荐
相关产品推荐

