2015-06-28 57 views
1

當使用findOneAndUpdate將upsert和setDefaultsOnInsert設置爲true時,我嘗試在數據庫中插入新用戶時遇到問題。我所試圖做的是設置以下模式的默認值:Mongoose setDefaultsOnInsert和2dsphere索引不起作用

var userSchema = new mongoose.Schema({ 
    activated: {type: Boolean, required: true, default: false}, 
    facebookId: {type: Number, required: true}, 
    creationDate: {type: Date, required: true, default: Date.now}, 
    location: { 
     type: {type: String}, 
     coordinates: [] 
    }, 
    email: {type: String, required: true} 
}); 

userSchema.index({location: '2dsphere'}); 

findOneAndUpdate代碼:

model.user.user.findOneAndUpdate(
     {facebookId: request.params.facebookId}, 
     { 
      $setOnInsert: { 
       facebookId: request.params.facebookId, 
       email: request.payload.email, 
       location: { 
        type: 'Point', 
        coordinates: request.payload.location.coordinates 
       } 
      } 
     }, 
     {upsert: true, new: true, setDefaultsOnInsert: true}, function (err, user) { 
      if (err) { 
       console.log(err); 
       return reply(boom.badRequest(authError)); 
      } 
      return reply(user); 
     }); 

正如你可以看到我還可以存儲用戶的緯度和經度,這就是問題開始的地方。當findOneAndUpdate被稱爲我得到這個錯誤:

{ [MongoError: exception: Cannot update 'location' and 'location.coordinates' at the same time] 
name: 'MongoError', 
message: 'exception: Cannot update \'location\' and \'location.coordinates\' at the same time', 
errmsg: 'exception: Cannot update \'location\' and \'location.coordinates\' at the same time', 
code: 16836, 
ok: 0 } 

當我刪除了2dsphere指數和所有與位置相關的代碼,它不會把我的creationDate。我做錯了什麼?

回答

2

setDefaultsOnInsert選項使用$setOnInsert操作執行其功能,而且看起來這是相互矛盾的用自己的使用$setOnInsert設置location

一種解決方法是刪除setDefaultsOnInsert選項,並把它們都放在自己的$setOnInsert運營商:

model.user.user.findOneAndUpdate(
     {facebookId: request.params.facebookId}, 
     { 
      $setOnInsert: { 
       activated: false, 
       creationDate: Date.now(), 
       email: request.payload.email, 
       location: { 
        type: 'Point', 
        coordinates: request.payload.location.coordinates 
       } 
      } 
     }, 
     {upsert: true, new: true}, 
     function (err, user) { 
      if (err) { 
       console.log(err); 
       return reply(boom.badRequest(authError)); 
      } 
      return reply(user); 
     }); 
+0

我正在考慮這樣做,但這是否意味着貓鼬中存在一個錯誤? – Jdruwe

+1

@Jdruwe是的,我認爲這個問題是Mongoose中的一個錯誤。在這種情況下,它不應該試圖將'location.coordinates'設置爲空數組。 – JohnnyHK

+1

好的,我在github回購上創建了一個問題,謝謝你的時間! – Jdruwe

0

其中一個開發者的回答我的問題,在GitHub上,並添加它作爲4.0的一個里程碑。 8日發佈,這是他的解決方法:

$setOnInsert: { 
      facebookId: request.params.facebookId, 
      email: request.payload.email, 
      'location.type': 'Point', 
      'location.coordinates': request.payload.location.coordinates 
    } 

他的解決方案並沒有爲我工作,我得到以下錯誤:

{ [MongoError: exception: insertDocument :: caused by :: 16755 Can't extract geo keys from object, malformed geometry?: { _id: ObjectId('559024a0395dd599468e4f41'), facebookId: 1.020272578180189e+16, location: { coordinates: [], type: "Point" }, email: "[email protected]", gender: "male", lastName: "Druwé", firstName: "Jeroen", __v: 0, activated: false, creationDate: new Date(1435509921264), familyDetails: { children: [] } }] 
+0

當我試圖擺脫錯誤,但'location.coordinates'結束爲'[]'而不是來自請求的座標。 – JohnnyHK

+0

我也收到了一個空的[]和我在答案中添加的錯誤。奇怪的是你沒有得到這個MongoError。 – Jdruwe