这是我的架构定义:
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上搜索过这个问题,然而,对我来说没有任何解决方案。请帮忙,谢谢。
答案 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'
}
是不同的键。