模型错误的路径值转换为 ObjectId 失败

Posted

技术标签:

【中文标题】模型错误的路径值转换为 ObjectId 失败【英文标题】:Cast to ObjectId failed for value at path for model error 【发布时间】:2020-10-13 08:15:45 【问题描述】:

这是我的个人资料架构:

const mongoose = require('mongoose');

const ProfileSchema = new mongoose.Schema(
    user: 
        // Special field type because
        // it will be associated to different user
        type: mongoose.Schema.Types.ObjectId,
        ref: 'user',
    ,
    company: 
        type: String,
    ,
    website: 
        type: String,
    ,
    location: 
        type: String,
    ,
    status: 
        type: String,
        required: true,
    ,
    skills: 
        type: [String],
        required: true,
    ,
    bio: 
        type: String,
    ,
    githubusername: 
        type: String,
    ,
    experience: [
        
            title: 
                type: String,
                required: true,
            ,
            company: 
                type: String,
                required: true,
            ,
            location: 
                type: String,
            ,
            from: 
                type: Date,
                required: true,
            ,
            to: 
                type: Date,
            ,
            current: 
                type: Boolean,
                default: false,
            ,
            description: 
                type: String,
            ,
        ,
    ],
    education: [
        
            school: 
                type: String,
                required: true,
            ,
            degree: 
                type: String,
                required: true,
            ,
            fieldofstudy: 
                type: String,
                required: true,
            ,
            from: 
                type: Date,
                required: true,
            ,
            to: 
                type: Date,
            ,
            current: 
                type: Boolean,
                default: false,
            ,
            description: 
                type: String,
            ,
        ,
    ],
    social: 
        youtube: 
            type: String,
        ,
        twitter: 
            type: String,
        ,
        facebook: 
            type: String,
        ,
        linkedin: 
            type: String,
        ,
        instagram: 
            type: String,
        ,
    ,
    date: 
        type: Date,
        default: Date.now,
    ,
);

module.exports = Profile = mongoose.model('profile', ProfileSchema);

   

这是我的视图 api。它不起作用。对于模型profile,路径_id 处的值 'experience._id': '5edcb6933c0bb75b3c90a263' 仅返回Cast to ObjectId 失败

router.get('/experience/viewing/:viewexp_id', auth, async (req, res) => 
    try 
        const exp = await Profile.findById(
            'experience._id': req.params.viewexp_id,
        );

        if (!exp) 
            return res.status(404).json( msg: 'Experience not found' );
        

        res.json(exp);
     catch (err) 
        console.error(err.message);
        res.status(500).send(err.message);
    
);

我该如何解决这个问题?我尝试查看相同错误的堆栈溢出。它似乎仍然不起作用。

这就是我想要达到的目标

【问题讨论】:

【参考方案1】:

router.post(
  "/",
  [
    auth,
    [
      check("status", "status is required").not().isEmpty(),
      check("skills", "skills is required").not().isEmpty(),
    ],
  ],
  async (req, res) => 
    const errors = validationResult(req);
    if (!errors.isEmpty()) 
      return res.status(400).json( errors: errors.array() );
    

    const 
      company,
      website,
      location,
      bio,
      status,
      githubuername,
      skills,
      youtube,
      facebook,
      twitter,
      instagram,
      linkedin,
     = req.body;

    const profileFileds = ;
    profileFileds.user = req.user.id;
    if (company) profileFileds.company = company;
    if (website) profileFileds.website = website;
    if (location) profileFileds.location = location;
    if (bio) profileFileds.bio = bio;
    if (status) profileFileds.status = status;
    if (githubuername) profileFileds.githubuername = githubuername;
    if (skills) 
      profileFileds.skills = skills.split(",").map((skill) => skill.trim());
    

    //Build profile object
    profileFileds.social = ;

    if (youtube) profileFileds.social.youtube = youtube;
    if (twitter) profileFileds.social.twitter = twitter;
    if (facebook) profileFileds.social.facebook = facebook;
    if (linkedin) profileFileds.social.linkedin = linkedin;
    if (instagram) profileFileds.social.instagram = instagram;

    try 
      let profile = await Profile.findOne( user: req.user.id );

      if (profile) 
        //update
        profile = await Profile.findOneAndUpdate(
           user: req.user.id ,
           $set: profileFileds ,
           new: true 
        );
        return res.json(profile);
      

      //Create profile
      profile = new Profile(profileFileds);
      await profile.save();
      res.json(profile);
     catch (err) 
      console.error(err.message);
      res.status(500).send("server Error");
    
  
);

【讨论】:

请不要只发布代码作为答案,还要解释您的代码的作用以及它如何解决问题的问题。带有解释的答案通常更有帮助、质量更好,并且更有可能吸引投票。【参考方案2】:

问题是您必须使用此函数mongoose.Types.ObjectId 将字符串_id 转换为mongoose object id,而我的建议是使用findOne 函数而不是findById

var mongoose = require('mongoose');

router.get('/experience/viewing/:viewexp_id', auth, async (req, res) => 
    
    try 

        let id = mongoose.Types.ObjectId(req.params.viewexp_id);
        
        const exp = await Profile.findOne(
             "experience._id": req.params.viewexp_id , 
            // This will show your sub record only and exclude parent _id
             "experience.$": 1, "_id": 0 
        );

        if (!exp) 
            return res.status(404).json( msg: 'Experience not found' );
        

        res.json(exp);

     catch (err) 
        console.error(err.message);
        res.status(500).send(err.message);
    

);

【讨论】:

非常感谢。我使用了您从 "experience._id": req.params.viewexp_id 到 "experience._id": id 声明的 id,因为您声明了它。 "_id": "5ed209b58c14a956648db0b4", "experience": [ "current": true, "_id": "5edcb6933c0bb75b3c90a263", "title": "JUNE 8 2020", "company" :“灰熊”,“位置”:“奎松市”,“来自”:“2012-01-25T16:00:00.000Z”,“描述”:“灰熊大师”] 最后,我返回该用户的 ID 是否正常?为什么包括在内?不仅仅是经验数据? 我不知道,但你可以从这个结果中排除主要的_id 在你的投影 "experience.$": 1. "_id": 0 中执行此操作,并在答案中进行编辑查看它,我会查看你的查询,当我今天有机会了解如何获得直接记录时。我赞成你的问题:)【参考方案3】:
var mongoose = require('mongoose');

router.get('/experience/viewing/:viewexp_id', auth, async (req, res) => 
try 
    const exp = await Profile.findOne(
        'experience._id': mongoose.Types.ObjectId(req.params.viewexp_id),
    );

    if (!exp) 
        return res.status(404).json( msg: 'Experience not found' );
    

    res.json(exp);
 catch (err) 
    console.error(err.message);
    res.status(500).send(err.message);

);

您正在保存对象 id 。但你的参数 id 是字符串。将其转换为 ObjectId。请检查我的解决方案。

【讨论】:

这将返回所有配置文件信息。它不会返回该用户的一种体验

以上是关于模型错误的路径值转换为 ObjectId 失败的主要内容,如果未能解决你的问题,请参考以下文章

护照注销()错误:对于模型“somemodel(不是用户模型)”的路径“_id”处的值“注销”,转换为 ObjectId 失败

模型的路径“_id”处的值“”转换为 ObjectId 失败

对于模型的路径“_id”处的值,转换为 ObjectId 失败

CastError:对于猫鼬中模型的路径“_id”处的值“findByName”,转换为 ObjectId 失败

CastError:对于猫鼬中模型的路径“_id”处的值“findByName”,转换为 ObjectId 失败

CastError:模型“Company”的路径“_id”处的值“...”转换为 ObjectId 失败