Mongoose保存_id'ss作为string而不是ObjectId

与Mongodb和Mongoose一起使用Nodejs。

我刚刚发现,Mongoose / Mongodb已经将自动生成的_id字段保存为string,而不是ObjectId。 Mongodb shell输出和示例文件:

> db.users.count({_id: {$type: 7}}) 2 > db.users.count({_id: {$type: 2}}) 4266 > db.users.find({_id: {$type: 7}},{_id:1}).limit(1) { "_id" : ObjectId("55f7df6fdb8aa078465ec6ec") } > db.users.find({_id: {$type: 2}},{_id:1}).limit(1) { "_id" : "558c3472c8ec50de6e560ecd" } 

4266 _id的(string)来自这个代码:

 var newUser = new ApiUser(); newUser.name = name; newUser.link = link; newUser.signupTime = new Date().getTime(); newUser.initialBrowser = initialBrowser; newUser.save(function(err) { if (err) res.json(err); else res.json('success'); }); 

和2 _id(ObjectId's)来自这个代码:

 var newUser = new User(); newUser.facebook.id = profile.id; newUser.facebook.token = token; newUser.name = profile.name.givenName + ' ' + profile.name.familyName; if (profile.emails) { newUser.facebook.email = (profile.emails[0].value || '').toLowerCase(); } newUser.facebook.gender = profile.gender; newUser.facebook.profilePic = profile.photos[0].value; newUser.save(function(err) { if (err) return done(err); return done(null, newUser); }); 

User()和ApiUser()都引用相同的模型。 保存ObjectId的是在Passport.js的Facebookauthentication策略中

更新:这是我的用户架构:

 var mongoose = require('mongoose'); var bcrypt = require('bcrypt-nodejs'); var Schema = mongoose.Schema; // define the schema for our user model var userSchema = Schema({ name: String, email: String, link: Number, location: String, residence: String, age: Number, gender: String, subject: String, signupTime: Number, finishTime: Number, shared: String, search: String, shareFriend: String, local : { email : String, password : String }, facebook : { id : String, token : String, email : String, name : String, gender : String, profilePic : String }, interestsSummary: [Number], interests: [{name: String, iType: String}], valuesSummary: [Number], values: [{name: String}], traitsSummary: [Number], traits: [{name: String}], bio: String, friendInterests: Number, friendValues: Number, friendPersonality: Number, surveyLength: String, missedInfo: String, anythingElse: String, finalBrowser: String, consented: Boolean }, {collection: "users"}); // generating a hash userSchema.methods.generateHash = function(password) { return bcrypt.hashSync(password, bcrypt.genSaltSync(8), null); }; // checking if password is valid userSchema.methods.validPassword = function(password) { return bcrypt.compareSync(password, this.local.password); }; // create the model for users and expose it to our app module.exports = mongoose.model('User', userSchema); 

问题是,我似乎无法查询基于string,这是给我的问题的mongodb:

  ApiUser.findById(req.body.friend,{name:1},function(err,user) { console.log(user); }) 

这将返回null,除非我使用正确的_idsearch2个用户之一。 Req.body.friend是_id,它是一个string。 我怎样才能改变所有的文件的_id的ObjectId的,或用string_id的查询现有的文件?

这是一个非常具体的问题,但如果有人偶然遇到类似的问题,我的问题是,我写了一个文件与我所有的文件作为json在远程服务器上使用mongoimport。

问题是JSON.stringify()会将一个objectId转换为一个string。 为了解决这个问题,我写了一个小脚本来遍历用户数组中的所有对象,并使用以下命令将所有_id的对象转换回objectId:

 var mongoose = require('mongoose'); user._id = mongoose.Types.ObjectId(users[i]._id); 

然后在我的mongoose模型上用更新的文档调用Model.create()来批量插入,并删除原始文档