首页 > 解决方案 > Mongodb Cast错误:部分url被发送到_id。如何从请求中获取 id

问题描述

我一直在谷歌和 StackOverflow 上搜索,这个错误已经存在了很长一段时间,但没有一个建议的解决方案适合我的问题。

我有一个端点

router.get('/posts/me', authController.isLoggedIn, catchErrors(blogController.myPosts))

检查该用户有哪些帖子

在控制器上我有:

exports.myPosts = async (req, res) => {

    const posts = await Post.findById({author: {$eq: req.user._id}})

    res.json({'response':posts.length > 0 ? posts : 'You have no blog posts ☹️ ',
              'status':200})

}

Mongo 返回一个奇怪的错误:

CastError: Cast to ObjectId failed for value "{ _id: 'me' }" at path "_id" for model "Post"

其中“我”是 URL 的最后一部分。如果我改变,这部分错误也会改变。

我不想按 Id 查找帖子,我需要找到所有作者 id 等于 req.user_.id 的帖子

$where 运算符在我的地图集层上无效,我读到它并不是很有效。但问题是如何克服该错误并获取用户创建的所有帖子的列表?

完整的错误信息:

CastError: Cast to ObjectId failed for value "{ _id: 'me' }" at path "_id" for model "Post"
    at new CastError (F:\test\Projects\test\Backend\node_modules\mongoose\lib\error\cast.js:29:11)
    at ObjectId.cast (F:\test\Projects\test\Backend\node_modules\mongoose\lib\schema\objectid.js:244:11)
    at ObjectId.SchemaType.applySetters (F:\test\Projects\test\Backend\node_modules\mongoose\lib\schematype.js:948:12)
    at ObjectId.SchemaType._castForQuery (F:\test\Projects\test\Backend\node_modules\mongoose\lib\schematype.js:1362:15)
    at ObjectId.SchemaType.castForQuery (F:\test\Projects\test\Backend\node_modules\mongoose\lib\schematype.js:1352:15)
    at ObjectId.SchemaType.castForQueryWrapper (F:\test\Projects\test\Backend\node_modules\mongoose\lib\schematype.js:1331:15)
    at cast (F:\test\Projects\test\Backend\node_modules\mongoose\lib\cast.js:252:34)
    at model.Query.Query.cast (F:\test\Projects\test\Backend\node_modules\mongoose\lib\query.js:4607:12)
    at model.Query.Query._castConditions (F:\test\Projects\test\Backend\node_modules\mongoose\lib\query.js:1790:10)
    at model.Query.<anonymous> (F:\test\Projects\test\Backend\node_modules\mongoose\lib\query.js:2045:8)
    at model.Query._wrappedThunk [as _findOne] (F:\test\Projects\test\Backend\node_modules\mongoose\lib\helpers\query\wrapThunk.js:16:8)
    at process.nextTick (F:\test\Projects\test\Backend\node_modules\kareem\index.js:369:33)
at process._tickCallback (internal/process/next_tick.js:61:11)

我正在使用 passport.js 来处理身份验证

exports.isLoggedIn = (req, res, next) =>{
    if(req.isAuthenticated()){
        return next();
    }
    res.status(401).json({'online':false, 
              'message':'Oops you must be logged in to do that ', 
              'status':401})
 }

为了更好地解释我在做什么......我的 index.js 文件包含我的所有路由,我想使用 get 请求调用路由,该请求将(如果用户已登录)调用将查询数据库搜索的方法该用户发布的所有帖子。url 是固定的,我没有在 db 查询中使用它。我为查询获取了请求中的用户 ID 的值。

如果我在 url 上传递 id 并使用它查询 db,则错误消失但 db 始终返回 null。

当我收到所有帖子(使用另一条路线)时,我得到了以下回复:

 "response": [
        {
        "text": [
            "We still need to update this"
        ],
        "tags": [],
        "images": [],
        "_id": "5d4c1c0266afb7629c2513b9",
        "title": "Second Post",
        "description": "This is the second post for our platform",
        "author": "5d4923257b914233b834a7fb",
        "created": "2019-08-08T12:56:34.720Z",
        "slug": "second-post",
        "id": "5d4c1c0266afb7629c2513b9"
      }

重点在作者id:5d4923257b914233b834a7fb

如果我将端点更改为使用 url 中的 id

 router.get('/posts/:id', authController.isLoggedIn, catchErrors(blogController.myPosts))

const posts = await Post.find({author: {$eq: req.params.id}})

响应为 null,错误消失但 mongo 返回 null。

标签: node.jsmongodbexpress

解决方案


错误是您正在传递一个字符串,在这种情况下me,而不是 MongoDB ObjectID。

我猜这条路线行不通而其他路线行不通的原因是其他路线是这样的:/posts/:post_id. 您的代码在此/posts/me路由中假定me为帖子 ID,并尝试使用 ObjectID 查找me显然会崩溃的帖子。

如果您粘贴 index.js 的内容,我将能够查明问题所在。

至于当你使用请求参数中的 id 时没有得到结果,摆脱eq操作数并使用用户 id 调用路由

await Post.find({ author: req.params.id })

推荐阅读