英文:
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
id
ke dalam metodeFood.create()
.
Jika Anda ingin membuat field id
sendiri, lakukan hal berikut:
- Deklarasikan field
id
dengan tipeString
dalam 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
id
field to theFood.create()
method.
If you want to create an id
field by yourself, do:
- Declare an
id
field with aString
type 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();
}
})();
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论