2011-12-13 56 views
3

當我這樣做:如何使用基於_id的Mongoose進行連接?

client_id = req.param("client_id") ? null 
client = 
    name: req.param "clientName" 
    status: 'active' 

Client.update {_id: client_id}, client, {upsert: true}, (err, updRes) -> 
    if err 
    res.json 
     error: "Couldn't create client" 
    else 
    res.json client 

這將創建一個新的客戶端記錄,除了有null_id場。我認爲這是因爲upsert的插入部分看起來是query來創建文檔。我該如何做,如果沒有找到文檔,然後插入一個新的ObjectId

回答

8

不知道你是否已經認識到這一點,但如果你不想遇到像上面提到的穆斯塔法這樣的獨特的關鍵約束問題,我已經做到了這一點,通過使用貓鼬的findByIdAndUpdate

// require mongoose 

client_id = req.param("client_id") ? new mongoose.Types.ObjectId 
client = 
    name: req.param "clientName" 
    status: 'active' 

Client.findByIdAndUpdate client_id, client, {upsert: true}, (err, updRes) -> 
    if err 
    res.json 
     error: "Couldn't create client" 
    else 
    res.json client 

我從來沒有寫過CoffeeScript,所以請原諒我,如果有些語法錯誤,但我認爲它應該是相當明顯的,我想要做的。

有一點需要注意的是,你需要確保client_id既不是空字符串(因爲這會導致'無效的ObjectID'錯誤),也不是null(因爲貓鼬似乎從你所在的位置推斷新文檔的ID查詢)。在這種情況下,我創建了一個新的ObjectId,這會導致查詢錯過,並因此通過{upsert:true}創建一個具有該ID的新文檔。

這似乎已經解決了我的問題。

+0

在Mongoose v 4.0之後,您需要明確地將'new'選項設置爲'true',因爲4.0之前的默認值爲'true',但現在在4.0之後爲'false'。參考[此堆棧溢出問題](http://stackoverflow.com/a/30396464/404699)和[這些發行說明](https://github.com/Automattic/mongoose/wiki/4.0-Release-Notes#backwards -breaking-變化)。 – steampowered

2

所有你有貓鼬做的是調用保存在客戶端上,貓鼬會找出自身,如果它是一個更新或插入:

client_id = req.param("client_id") ? null 
client_data = 
    name: req.param "clientName" 
    status: 'active' 
    _id: client_id 

client = new Client(client_data) 
client.save (err) -> 
    if err 
    res.json 
     error: "Couldn't save client" 
    else 
    res.json client 

注:客戶是貓鼬模型。

+0

所以不需要upserts? – Shamoon

+1

我可以告訴你,我已經在我的代碼中實際使用了它,既可以用於插入和更新,也可以工作,所以不需要upserts。保佑貓鼬ODM :) – alessioalex

+0

如果client_id爲空,會用新的'_id'保存嗎? – Shamoon