如何使用Mongoose的自定义_id加载文档?

时间:2014-01-03 01:56:41

标签: node.js mongodb mongoose

这是我的架构定义:

var DocSchema = new mongoose.Schema({
  _id: {
    name: String,
    path: String
  },
  label: String,
  ...
});
mongoose.model('Doc', DocSchema, 'doc_parse_utf8');
var Doc = mongoose.model('Doc');

其他程序已将文件插入mongodb。然后我试着查询文件:

Doc.findOne({_id:{name:name,path:path}}, function(err, doc){
  if (err && err_handler) {
    err_handler(err);
  } else if(callback) {
    callback(doc);
  }
});

但是,会报告投射错误:

{ message: 'Cast to ObjectId failed for value "[object Object]" at path "_id"',
  name: 'CastError',
  type: 'ObjectId',
  value: { name: 'mobile', path: 'etc/' },
  path: '_id' }

我在mongoose的文档,谷歌和statckoverflow.com上搜索过这个问题,然而,对我来说没有任何解决方案。请帮忙,谢谢。

2 个答案:

答案 0 :(得分:6)

您需要做的就是通过将_id设置为Mixed来覆盖var UserSchema = new Schema({ _id: Schema.Types.Mixed, name: String }); 类型。

find

这会导致Mongoose基本上忽略对象的细节。

现在,当您使用_id时,它将起作用(几乎与预期一样)。

我警告您,您需要确定您使用的_id对象的属性顺序必须以完全相同的顺序提供,否则var User = mongoose.model('User', UserSchema); var testId = { name: 'wiredprairie', group: 'abc'}; var u = new User({_id: testId , name: 'aaron'}); u.save(function(err, results) { User.find().where("_id", testId) .exec(function(err, users) { console.log(users.length); }); }); 将不被认为是相同的。

当我尝试这样做时:

0

控制台输出为{ "_id" : { "group" : "abc", "name" : "wiredprairie" }, "name" : "aaron", "__v" : 0 }

我注意到MongoDB中的实际数据存储方式与我认为保存的方式不同:

name

正如您所看到的,我编码时不是group然后var User = mongoose.model('User', UserSchema); var testId = { name: 'wiredprairie', group: 'abc'}; var u = new User({_id: testId , name: 'aaron'}); u.save(function(err, results) { User.find().where("_id", { group: 'abc', name: 'wiredprairie'}) .exec(function(err, users) { console.log(users.length); }); }); 。 (这是按字母顺序排列的,回想起来是有意义的。)

所以,相反,我这样做了:

1

然后,控制台输出为{{1}}。

答案 1 :(得分:1)

我认为你应该重新设计你的架构。如果数据库已经在服务上,并且现在无法更改,您可以临时使用它来解决问题:

mongoose.connection.on('open', function () {
  mongoose.connection.db.collection('doc_parse_utf8').find({
      _id: {
        name: 'mobile',
        path: 'etc/'
      }
  }).toArray(function(err, docs) {
      console.log(err || docs)
  })  
})

据我所知,如果您在对象find中选择不同的字段顺序,则方法将无效,因为

  _id: {
    name: 'mobile',
    path: 'etc/'
  }

  _id: {
    path: 'etc/',
    name: 'mobile'
  }

是不同的键。