IT

Mongoose 오류는 무엇입니까? 경로“_id”에서 값 XXX에 대해 ObjectId로 캐스트하지.

lottoking 2020. 8. 26. 08:10
반응형

Mongoose 오류는 무엇입니까? 경로“_id”에서 값 XXX에 대해 ObjectId로 캐스트하지.


에 요청 보낼 때 /customers/41224d776a326fb40f000001와있는 문서 _id 41224d776a326fb40f000001가 존재하지 않습니다, doc이다 null와 나는 반환하고 있습니다 404:

  Controller.prototype.show = function(id, res) {
    this.model.findById(id, function(err, doc) {
      if (err) {
        throw err;
      }
      if (!doc) {
        res.send(404);
      }
      return res.send(doc);
    });
  };

그러나 _id몽구스가 예상하는 "형식"(내 생각에) 일치 여부하지 않는과 경우 예를 들어 GET /customers/foo이상한 오류가 반환됩니다.

CastError : "_id"경로의 "foo"값에 대해 ObjectId로 캐스트하지.

오류는 무엇입니까?


Mongoose의 findById메서드는 id매개 변수를 모델의 _id필드 유형으로 캐스팅 하여 일치하는 문서를 제대로 쿼리 할 수 ​​있도록합니다. 이것은 ObjectId이지만 "foo"유효한 ObjectId가 아니 캐스트가 실패합니다.

41224d776a326fb40f000001문자열이 유효한 ObjectId가 때문에이기 발생하지 않습니다 .

이 문제를 해결 하기 전에 한 가지 방법은 findById호출 id유효한 ObjectId인지 여부를 확인하기 위해 확인을 추가하는 것입니다.

if (id.match(/^[0-9a-fA-F]{24}$/)) {
  // Yes, it's a valid ObjectId, proceed with `findById` call.
}

ObjectID 확인을 위해 기존 함수를 사용합니다.

var mongoose = require('mongoose');
mongoose.Types.ObjectId.isValid('your id here');

해당 어깨를 다음과 같이 구문 분석하고 ObjectId있습니까?

여기 내 응용 프로그램에서 내가하는 일은 다음과 달라집니다.

ObjectId.fromString( myObjectIdString );


_id : String .in schema를 추가 한 다음 작업을 시작 하는 것과 동일한 문제가 있습니다 .


경로 변수를 이동하는 다른 경로

// require express and express router

const express = require("express");
const router = express.Router();

// move this `/post/like` route on top

router.put("/post/like", requireSignin, like);

// keep the route with route parameter `/:postId` below regular routes

router.get("/post/:postId", singlePost);

다음과 같이 ObjectId.isValid를 사용할 수도 있습니다.

if (!ObjectId.isValid(userId)) return Error({ status: 422 })

이 오래된 질문이지만 express-validator 패키지를 사용하여 요청 변수를 확인할 수도 있습니다.

express-validator 버전 4 (최신) :

validator = require('express-validator/check');

app.get('/show/:id', [

    validator.param('id').isMongoId().trim()

], function(req, res) {

    // validation result
    var errors = validator.validationResult(req);

    // check if there are errors
    if ( !errors.isEmpty() ) {
        return res.send('404');
    }

    // else 
    model.findById(req.params.id, function(err, doc) { 
        return res.send(doc);
    });

});

컴퓨터 유효성 검사기 버전 3 :

var expressValidator = require('express-validator');
app.use(expressValidator(middlewareOptions));

app.get('/show/:id', function(req, res, next) {

    req.checkParams('id').isMongoId();

    // validation result
    req.getValidationResult().then(function(result) {

        // check if there are errors
        if ( !result.isEmpty() ) {
            return res.send('404');
        }

        // else
        model.findById(req.params.id, function(err, doc) {
            return res.send(doc);
        });

    });

});

 if(mongoose.Types.ObjectId.isValid(userId.id)) {
        User.findById(userId.id,function (err, doc) {
            if(err) {
                reject(err);
            } else if(doc) {
                resolve({success:true,data:doc});
            } else {
                reject({success:false,data:"no data exist for this id"})

            }
        });
        } else {
            reject({success:"false",data:"Please provide correct id"});
        }

가장 좋은 것은 유효성을 확인하는 것입니다.


//Use following to check if the id is a valid ObjectId?

var valid = mongoose.Types.ObjectId.isValid(req.params.id);
if(valid)
{
  //process your code here
} else {
  //the id is not a valid ObjectId
}

@gustavohenke 솔루션을 수정하여 ObjectId 캐스팅의 실패를 유효성 검사 방법으로 활용하기 위해 원본 코드감싸는 try-catch에서 캐스팅 ObjectId를 구현했습니다 .

Controller.prototype.show = function(id, res) {
  try {
    var _id = mongoose.Types.ObjectId.fromString(id);



    // the original code stays the same, with _id instead of id:

    this.model.findById(_id, function(err, doc) {
      if (err) {
        throw err;
      }
      if (!doc) {
        res.send(404);
      }
      return res.send(doc);
    });



  } catch (err) {
    res.json(404, err);
  }
};

또는 할 수 있습니다

var ObjectId = require('mongoose').Types.ObjectId; var objId = new ObjectId( (param.length < 12) ? "123456789012" : param );

여기에서 언급했듯이 $ or 조건이있는 Mongoose의 찾기 방법이 제대로 작동하지 않습니다.


mongoose.Types.ObjectId('your id')쿼리의 조건에 항상 사용 하면 쿼리를 실행하기 전에 id 필드의 유효성을 검사하므로 앱이 충돌하지 않습니다.


이 문제를 해결하는 방법은 ID를 문자열로 변환하는 것입니다.

나는 backtick로 멋진 것을 좋아합니다. `${id}`

오버 헤드없이 문제를 해결해야합니다.


ObjectId는 다음과 같이 구성됩니다.

  1. Unix 시대 이후 초를 나타내는 4 바이트 값
  2. 5 바이트 임의 값 (컴퓨터 ID 3 바이트 및 프로세서 ID 2 바이트)
  3. 임의의 값으로 시작하는 3 바이트 카운터.

objectId가 유효한지 확인하는 올바른 방법은 ObjectId 클래스 자체의 정적 메서드를 사용하는 것입니다.

mongoose.Types.ObjectId.isValid (sample_object_id)


문자열을 ObjectId로 캐스트

import mongoose from "mongoose"; // ES6 or above
const mongoose = require('mongoose'); // ES5 or below

let userid = _id
console.log(mongoose.Types.ObjectId(userid)) //5c516fae4e6a1c1cfce18d77

ObjectID 오류 감지 및 수정

mongoose를 사용하여 항목을 삭제하려고 할 때이 문제가 발생하고 동일한 오류가 발생했습니다. 반환 문자열을 살펴본 후 반환 된 문자열 내부에 추가 공백이있어 오류가 발생했습니다. 그래서 여기에 제공된 몇 가지 답변을 적용하여 잘못된 ID를 감지 한 다음 문자열에서 추가 공백을 제거했습니다. 마지막으로 문제를 해결하는 데 도움이 된 코드는 다음과 같습니다.

const mongoose = require("mongoose");
mongoose.set('useFindAndModify', false);  //was set due to DeprecationWarning: Mongoose: `findOneAndUpdate()` and `findOneAndDelete()` without the `useFindAndModify`



app.post("/delete", function(req, res){
  let checkedItem = req.body.deleteItem;
  if (!mongoose.Types.ObjectId.isValid(checkedItem)) {
    checkedItem = checkedItem.replace(/\s/g, '');
  }

  Item.findByIdAndRemove(checkedItem, function(err) {
    if (!err) {
      console.log("Successfully Deleted " + checkedItem);
        res.redirect("/");
      }
    });
});

이것은 나를 위해 일했으며 다른 항목이 반환 문자열에 나타나기 시작하면 비슷한 방법으로 제거 할 수 있다고 가정합니다.

이게 도움이 되길 바란다.


누군가가 이것에 부딪히면 나를 위해 해결 된 것은 require의 작은 따옴표에서`.

대신에:

const something = require('./models/something');

사용하다:

const something = require(`./models/something`);

재미있게 들리지만 실제로는 작동합니다.


제 경우에는 _id: Object스키마 에 추가해야했는데 모든 것이 잘 작동했습니다.

참고 URL : https://stackoverflow.com/questions/14940660/whats-mongoose-error-cast-to-objectid-failed-for-value-xxx-at-path-id

반응형