Mongodb无法按ID查询子文档(返回null)

时间:2019-03-27 20:36:49

标签: javascript node.js database mongodb mongoose

所以我有这个猫鼬模式:

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}

我正在尝试在post的comment数组中查询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是正确的-为什么找不到注释文档?

编辑:

我通过这样设置objectID尝试了此解决方案(Can't find documents searching by ObjectId using Mongoose):

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:  []

因此,尽管它似乎比我的解决方案要好,但这还不是解决方案。

2 个答案:

答案 0 :(得分:1)

无论您认为多少,都不会查询ObjectId。您正在查询编码为hexidecial字符串的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)上的此处搜索“猫鼬类型转换ObjectId”(不带引号;或者只是“猫鼬ObjectId”…),您会发现很多答案,因为这对于猫鼬用户来说是一个特别常见的问题。

答案 1 :(得分:0)

一旦尝试先检查参考数据,然后查询注释的_id。

*除了评论ID外,还可以从前端获取帖子ID,这样会更容易。

Post.findOne({_id:'postId'})
.populate({
  path  : 'comment',
  match : { _id : 'commentId' }
})
.exec(...);