2015-09-16 68 views
2

在Mongodb和Mongoose中使用Nodejs。Mongoose保存_id'ss作爲字符串而不是ObjectId

我剛剛發現Mongoose/Mongodb已經將自動生成的_id字段保存爲字符串,而不是ObjectId。 MongoDB的外殼輸出和樣本文件:

> 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的(弦)來自這個代碼:

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的)來自這個代碼:

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

更新Facebook的身份驗證策略:這裏是我的用戶模式:

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); 

的問題是,我似乎無法根據的那些查詢的MongoDB這是給我的問題:

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

這將返回null,除非我搜索2用戶之一與正確的_id。 Req.body.friend是_id,它是一個字符串。我怎樣才能將所有文檔的_id改爲ObjectId,或者用字符串_id查詢現有文檔?

+0

請顯示您的架構和示例文檔。請列出示例文檔,如mongodb shell中所示,而不是節點控制檯輸出,因爲前者將正確顯示類型信息。 –

+0

發佈架構和示例文檔。另外,我很抱歉。輸出來自MongoDB外殼。 – KDogg

+0

這裏最合乎邏輯的情況是架構已被更改或其他代碼是導致此問題的原因。 Mongoose需要兩個特定的設置,以便以任何方式寫入字符串,當然不是ObjectId作爲字符串。你應該可以通過一些簡單的腳本將字符串值轉換爲ObjectId。如果有這樣的代碼,那不是你指向的代碼。 –

回答

1

這是一個非常具體的問題,但如果有人碰巧遇到過類似的問題,我的問題是我用我的所有文檔寫了一個文件作爲json在遠程服務器上使用mongoimport。

問題是JSON.stringify()會將objectId轉換爲字符串。要解決它,我寫的只是寫了一個小腳本遍歷我的用戶陣列中的所有對象,並轉換所有_id的回OBJECTID的使用下面的命令:

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

然後在我的貓鼬模型調用Model.create()用更新的文件批量插入,並刪除原始文件

相關問題