英文:
ValidationError: Cast to ObjectId failed for value 'X' (type string) at path '_id' - MongoDB
问题
I am here to provide you with a translation of the code and error message you provided. Here is the translation:
错误消息:
ValidationError: 食品验证失败:_id:值“1”(类型字符串)在路径“_id”上的ObjectId转换失败,原因是“BSONError”
在 model.Document.invalidate (/backend/node_modules/mongoose/lib/document.js:3157:32)
在 model.$set (/backend/node_modules/mongoose/lib/document.js:1453:12)
在 model.set (/backend/node_modules/mongoose/lib/helpers/document/compile.js:205:19)
在 model.idSetter (/backend/node_modules/mongoose/lib/helpers/schema/idGetter.js:41:12)
在 VirtualType.applySetters (/backend/node_modules/mongoose/lib/virtualtype.js:166:16)
在 model.$set (/backend/node_modules/mongoose/lib/document.js:1271:12)
在 model.$set (/backend/node_modules/mongoose/lib/document.js:1113:16)
在 model.Document (/backend/node_modules/mongoose/lib/document.js:164:12)
在 model.Model (/backend/node_modules/mongoose/lib/model.js:122:12)
在新的 model (/backend/node_modules/mongoose/lib/model.js:4682:15)
你的模型.ts看起来像这样:
export interface Food {
id: string;
name: string;
price: number;
tags: string[];
favorite: boolean;
stars: number;
imageUrl: string;
origins: string[];
cookTime: string;
url: string;
}
export const FoodSchema = new Schema<Food>(
{
name: {type: String, required: true},
price: {type: Number, required: true},
tags: {type: [String], required: true},
favorite: {type: Boolean, default: false},
stars: {type: Number, required: true},
imageUrl: {type: String, required: true},
origins: {type: [String], required: true},
cookTime: {type: String, required: true},
url: {type: String, required: true},
}, {
toJSON: {
virtuals: true
},
toObject: {
virtuals: true
},
timestamps: true
}
);
export const FoodModel = model<Food>('Food', FoodSchema);
而你的种子API看起来像这样:
router.get("/seed", async (req, res) => {
const foodsCount = await FoodModel.countDocuments();
if (foodsCount > 0) {
res.send("种子已完成");
return;
}
await FoodModel.create(sample_foods);
res.send("种子已完成");
})
你犯了什么错误?我是MongoDB的新手,正试图在教程的帮助下学习它。
请注意,我只提供了翻译,不回答关于解决问题的具体问题。如果你需要有关错误消息的帮助,可以提出具体问题,我将尽力回答。
英文:
I am trying to seed my mongodb database and I am running into this Validation error.
the error:
ValidationError: food validation failed: _id: Cast to ObjectId failed for value "1" (type string) at path "_id" because of "BSONError"
at model.Document.invalidate (/backend/node_modules/mongoose/lib/document.js:3157:32)
at model.$set (/backend/node_modules/mongoose/lib/document.js:1453:12)
at model.set (/backend/node_modules/mongoose/lib/helpers/document/compile.js:205:19)
at model.idSetter (/backend/node_modules/mongoose/lib/helpers/schema/idGetter.js:41:12)
at VirtualType.applySetters (/backend/node_modules/mongoose/lib/virtualtype.js:166:16)
at model.$set (/backend/node_modules/mongoose/lib/document.js:1271:12)
at model.$set (/backend/node_modules/mongoose/lib/document.js:1113:16)
at model.Document (/backend/node_modules/mongoose/lib/document.js:164:12)
at model.Model (/backend/node_modules/mongoose/lib/model.js:122:12)
at new model (/backend/node_modules/mongoose/lib/model.js:4682:15)
my model.ts looks like:
export interface Food {
id: string;
name: string;
price: number;
tags: string[];
favorite: boolean;
stars: number;
imageUrl: string;
origins: string[];
cookTime: string;
url: string;
}
export const FoodSchema = new Schema<Food>(
{
name: {type: String, required: true},
price: {type: Number, required: true},
tags: {type: [String], required: true},
favorite: {type: Boolean, default: false},
stars: {type: Number, required: true},
imageUrl: {type: String, required: true},
origins: {type: [String], required: true},
cookTime: {type: String, required: true},
url: {type: String, required: true},
}, {
toJSON: {
virtuals: true
},
toObject: {
virtuals: true
},
timestamps: true
}
);
export const FoodModel = model<Food>('Food', FoodSchema);
and my seed api looks like:
router.get("/seed", asynceHandler(
async (req,res)=>{
const foodsCount = await FoodModel.countDocuments();
if(foodsCount>0){
res.send("Seed is already done");
return;
}
await FoodModel.create(sample_foods);
res.send("Seed is done")
}
))
What am I doing wrong? I am a newbie to Mongodb and trying to learn it with the help of a tutorial.
答案1
得分: 2
id: '1' bukan id yang valid. Id yang valid dapat berupa string heksadesimal 24 karakter, Buffer biner 12 byte, atau angka. Mongoose mencoba mengonversi id: '1' menjadi ObjectId dan itulah mengapa Anda mendapatkan kesalahan.
Bagaimana proses pengonversian bekerja? Mongoose akan mencoba membuat ObjectId menggunakan new bson.ObjectId('1'). Di dalam konstruktor ObjectId, itu akan memvalidasi id masukan dan melemparkan BSONError.
Anda memiliki tiga pilihan:
Jika Anda ingin menggunakan _id yang ditambahkan oleh Mongoose ke dokumen, lakukan hal berikut:
-
Buat ObjectId secara eksplisit menggunakan
new mongoose.Types.ObjectId() -
Biarkan Mongoose membuat ObjectId untuk Anda. Anda tidak perlu menyertakan field
idke dalam metodeFood.create().
Jika Anda ingin membuat field id sendiri, lakukan hal berikut:
- Deklarasikan field
iddengan tipeStringdalam skema. Namun, Anda harus menjaga keunikan field ini dengan indeks unik.
Contoh:
import mongoose from 'mongoose';
import { config } from '../../config';
mongoose.set('debug', true);
console.log(mongoose.version);
const FoodSchema = new mongoose.Schema({
// id: String
name: String,
});
const Food = mongoose.model('Food', FoodSchema);
(async function main() {
try {
await mongoose.connect(config.MONGODB_URI);
// seed
const sample_foods = {
id: '1',
name: 'Pizza Pepperoni',
};
// create ObjectId explicitly
// await Food.create({ ...sample_foods, id: new mongoose.Types.ObjectId() });
// create ObjectId implicitly
const { id, ...rest } = sample_foods;
await Food.create(rest);
// declare an id field with the String type, then `id: '1'` is ok.
// await Food.create(sample_foods);
} catch (error) {
console.error(error);
} finally {
await mongoose.connection.close();
}
})();
英文:
id: '1' is not a valid id. The valid Id can be a 24 character hex string, 12 byte binary Buffer, or a number. Mongoose cast the id: '1' to an ObjectId failed, that's why you got the error.
How does cast work? Mongoose will try to create the ObjectId using new bson.ObjectId('1'), in the ObjectId constructor, it will validate the input id and throw a BSONError
You have three choices:
If you want to use the _id Mongoose added to the document, do:
-
create the ObjectId explicitly using
new mongoose.Types.ObjectId() -
Let the mongoose create ObjectId for you. You don't need to pass the
idfield to theFood.create()method.
If you want to create an id field by yourself, do:
- Declare an
idfield with aStringtype in the schema. But you have to maintain its uniqueness with a unique indexes.
E.g.
import mongoose from 'mongoose';
import { config } from '../../config';
mongoose.set('debug', true);
console.log(mongoose.version);
const FoodSchema = new mongoose.Schema({
// id: String
name: String,
});
const Food = mongoose.model('Food', FoodSchema);
(async function main() {
try {
await mongoose.connect(config.MONGODB_URI);
// seed
const sample_foods = {
id: '1',
name: 'Pizza Pepperoni',
};
// create ObjectId explicitly
// await Food.create({ ...sample_foods, id: new mongoose.Types.ObjectId() });
// create ObjectId implicitly
const { id, ...rest } = sample_foods;
await Food.create(rest);
// declare an id field with the String type, then `id: '1'` is ok.
// await Food.create(sample_foods);
} catch (error) {
console.error(error);
} finally {
await mongoose.connection.close();
}
})();
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论