首页 > 解决方案 > Mongodb 无法按 ID 查询子文档(返回 null)

问题描述

所以我有这个猫鼬模式:

var mongoose = require('mongoose');
var Schema = mongoose.Schema;

var CommentSchema = new Schema({
  body: {type: String, required: true, max: 2000},
  created: { type: Date, default: Date.now },
  flags: {type: Number, default: 0},
  lastFlag: {type: Date, default: Date.now()},
  imageBanned: {type: Boolean, default: false},
  fileName: {type: String, default: ""}
}, {
  writeConcern: {
    w: 0,
    j: false,
    wtimeout: 200
  }  
});

var PostSchema = new Schema({
  body: {type: String, required: true, max: 2000},
  created: { type: Date, default: Date.now },
  flags: {type: Number, default: 0},
  lastFlag: {type: Date, default: Date.now()},
  fileName: {type: String, default: ""},
  imageBanned: {type: Boolean, default: false},
  board: {type: String, default: ""},
  comments: [{ type: Schema.Types.ObjectId, ref: 'Comment' }]
}, {
  writeConcern: {
    w: 0,
    j: false,
    wtimeout: 200
  }  
});


var Post =  mongoose.model('Post', PostSchema);
var Comment = mongoose.model('Comment', CommentSchema)

module.exports = {Post, Comment}

我正在尝试在帖子的评论数组中查询评论。

这是我正在尝试的端点:

router.post('/flagComment', (req, res, next)=>{
  console.log('inside /flagComment')
  console.log('value of req.body: ', req.body)
  model.Post.findOne({"comments._id": req.body.id}).exec((err, doc)=>{
    if(err){
      console.log('there was an error: ', err)
    }
    console.log('the value of the found doc: ', doc)
    res.json({dummy: 'dummy'})
  })
})

但是,这会给出以下终端输出:

value of req.body:  { id: '5c9bd902bda8d371d5c808dc' }
the value of the found doc:  null

那不正确...我已验证 ID 是正确的 - 为什么找不到评论文档?

编辑:

我尝试了这个解决方案(Can't find documents search by ObjectId using Mongoose),方法是这样设置 objectID :

var ObjectId = require('mongoose').Types.ObjectId; 

router.post('/flagComment', (req, res, next)=>{
  console.log('inside /flagComment')
  console.log('value of req.body: ', req.body)
  console.log('value of objid req id : ',  ObjectId(req.body.id))
  model.Post.find({"comments._id": ObjectId(req.body.id)}).exec((err, doc)=>{
    if(err){
      console.log('there was an error: ', err)
    }
    console.log('the value of the found doc: ', doc)
    res.json({dummy: 'dummy'})
  })
})

我得到以下终端输出:

value of req.body:  { id: '5c9bd902bda8d371d5c808dc' }
value of objid req id :  5c9bd902bda8d371d5c808dc
the value of the found doc:  []

所以,这还不是一个解决方案,尽管它似乎比我所拥有的要好。

标签: javascriptnode.jsdatabasemongodbmongoose

解决方案


无论您认为自己是多少,您都不是在查询 ObjectId。您正在查询编码为十六进制字符串的 ObjectId,这不是一回事。正确地进行类型转换,您可能会取得更大的成功。

从 mongo (JS) REPL shell 编辑详细:

> // Omitting the _id, or generating a new one, are equivalent during insert.
> db.foo.insert({_id: ObjectId()})
WriteResult({ "nInserted" : 1 })

> db.foo.find()  // As expected, we get back our _real_ ObjectId value.
{ "_id" : ObjectId("5c9cfab873724727778c0730") }

> // Can we "insert the record again" using a string version of the ID?
> db.foo.insert({_id: "5c9cfab873724727778c0730"})
WriteResult({ "nInserted" : 1 })  // Sure as heck can! No unique violation!

> db.foo.find()  // Because THESE ARE NOT THE SAME
{ "_id" : ObjectId("5c9cfab873724727778c0730") }
{ "_id" : "5c9cfab873724727778c0730" }

在我们的 IRC 讨论之后,您似乎很难理解答案中的“可搜索词”。在 StackOverflow(或 Google,或 DDG)上搜索“mongoose typecast ObjectId”(不带引号;或只是“mongoose ObjectId”……),您会找到很多答案,因为这对于 Mongoose 用户来说是一个特别常见的问题。


推荐阅读