ValidationError: Cast to ObjectId failed for value 'X' (type string) at path '_id' – MongoDB

huangapple go评论54阅读模式
英文:

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 &quot;1&quot; (type string) at path &quot;_id&quot; because of &quot;BSONError&quot;
    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&lt;Food&gt;(
    {
        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&lt;Food&gt;(&#39;Food&#39;, FoodSchema);

and my seed api looks like:

router.get(&quot;/seed&quot;, asynceHandler(
    async (req,res)=&gt;{
        const foodsCount = await FoodModel.countDocuments();
        if(foodsCount&gt;0){
            res.send(&quot;Seed is already done&quot;);
            return;
        }
        await FoodModel.create(sample_foods);
        res.send(&quot;Seed is done&quot;)
    }
))

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 metode Food.create().

Jika Anda ingin membuat field id sendiri, lakukan hal berikut:

  • Deklarasikan field id dengan tipe String 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: &#39;1&#39; 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: &#39;1&#39; 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(&#39;1&#39;), 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 the Food.create() method.

If you want to create an id field by yourself, do:

  • Declare an id field with a String type in the schema. But you have to maintain its uniqueness with a unique indexes.

E.g.

import mongoose from &#39;mongoose&#39;;
import { config } from &#39;../../config&#39;;

mongoose.set(&#39;debug&#39;, true);
console.log(mongoose.version);

const FoodSchema = new mongoose.Schema({
    // id: String
	name: String,
});
const Food = mongoose.model(&#39;Food&#39;, FoodSchema);

(async function main() {
	try {
		await mongoose.connect(config.MONGODB_URI);
		// seed
		const sample_foods = {
			id: &#39;1&#39;,
			name: &#39;Pizza Pepperoni&#39;,
		};
		// 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: &#39;1&#39;` is ok.
		// await Food.create(sample_foods);
	} catch (error) {
		console.error(error);
	} finally {
		await mongoose.connection.close();
	}
})();

huangapple
  • 本文由 发表于 2023年7月24日 19:44:39
  • 转载请务必保留本文链接:https://go.coder-hub.com/76754152.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定