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는 다음과 같이 구성됩니다.
- Unix 시대 이후 초를 나타내는 4 바이트 값
- 5 바이트 임의 값 (컴퓨터 ID 3 바이트 및 프로세서 ID 2 바이트)
- 임의의 값으로 시작하는 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
스키마 에 추가해야했는데 모든 것이 잘 작동했습니다.
'IT' 카테고리의 다른 글
시뮬레이터에서 앱을 언어 수 없음 : Xcode beta 6 iOS 8 (0) | 2020.08.26 |
---|---|
오류 330 (net :: ERR_CONTENT_DECODING_FAILED) : (0) | 2020.08.26 |
Kotlin의 자바 정적 최종 필드와 동일한 것은 무엇인가요? (0) | 2020.08.26 |
node.js의 express.js 프레임 워크에서 교차 출처 리소스 공유 (CORS)를 활성화하는 방법 (0) | 2020.08.26 |
Twitter 부트 유효성 경고 메시지를 닫았다가 다시 메시지를 보냅니다. (0) | 2020.08.26 |