2013-10-08 181 views
0

假設我刪除了mongodb中的文檔或子文檔。我可以使用與刪除的相同的_id創建文檔/子文檔嗎?在這種情況下,我們假設,我們不能做更新操作,只是刪除和創建。刪除後刪除mongodb _id

例如使用Mongoid(Rails的寶石MongoDB的): 我們有角色模型

class Person 
    include Mongoid::Document 
    field :a, :type => String 
    embeds_many :personattributes 
end 
class Personattribute 
    include Mongoid::Document 
    field :myattribute, :type => String 
    embedded_in :person 
end 

而且在我的Rails控制器

class MyController < ApplicationController 
    ... 
    @[email protected] 
    ... 
    #controller will render page, an instance variable @the_attributes will be available as JSON in clientside 
end 

然後用戶做一些客戶端數據的修改。他們可以爲該人員數據添加一個或多個人員屬性。他們可以對其屬性進行一些更改。他們也可以刪除一些。 全部在客戶端。

然後通過AJAX調用,用戶將修改後的數據傳回JSON格式一樣

[{_id:"5253fd494db79bb271000009",myattribute:"test"},{...},...] 

在控制器檢索器檢索數據 然後完全用新的替換裏面的人的屬性列表。完全刪除和插入,無需更新。

class MyController < ApplicationController 
... 
@person.personattributes.delete_all #delete all attributes a @person has 
attributes=params[:attributes] 
attributes.map {|attr| 
    Personattribute.new(:_id => Moped::BSON::ObjectId.from_string(attr["_id"].to_s), :myattribute => attr["myattribute"]) 
} 

@person.personattributes=attributes 
@person.save 

... 
end 

我可以這樣做嗎?它只是意味着刪除全部,並插入所有並重用_ids。

如果不是,我會很樂意爲此採取一些更好的方法。

我不能做upsert,因爲被刪除的文檔將需要另一個循環來處理。

謝謝

+0

你爲什麼要保持相同的ID? –

+0

因爲其他數據(模型)是指特定的人物屬性。如果我更改了ID,那麼參考將被打破。感謝您提出澄清 –

回答

1

是的,你可以這樣做,但我會建議你不要這樣做。它似乎有很多的安全問題,如果有人修改了陣列手動

我可以寄:

[{_id:"5253fd494db79bb271000009",myattribute:"test_modified"},{...},...] 

甚至:

[{_id:"my_new_id_1",myattribute:"test_modified"},{...},...] 

這將引發異常

Moped::BSON::ObjectId.from_string "my_new_id_1" #=> raises an Exception 

嘗試類似:

attributes=params[:attributes] 
attributes.each do |attr| 
    @person.personattributes.find(attr["_id"]).myattribute = attr["myattribute"] 
    #or @person.personattributes.find(attr["_id"]).try(:myattribute=,attr["myattribute"]) 
end 

可能在未來,您想要更改操作並只發送數組中的修改後的人物屬性而不是所有人物屬性。那麼如果你delete_all並且只用發送的personattributes重建personattributes,你會怎麼做?

編輯

這種處理personattributes更新。創建或刪除personattributes應該在不同的操作:

創建行動

@person.personattributes.push Personattribute.new(my_attribute: params[:my_attribute]) 

刪除操作

@person.personattributes.delete(params[:personattribute_id]) 
+0

感謝您的回答。我會嘗試。如果它有效,我可以接受你的答案:)。我只是想知道,在你寫的解決方案中,我仍然無法獲得在客戶端完成刪除操作的解決方案。儘管如此,我也可以嘗試發送修改後的屬性的方法。 –

+0

我已經編輯了答案 –

+0

注意到感謝...我會盡快嘗試。 –

0

是的,您可以繼續使用相同的_id。他們只需要在一個集合中獨一無二 - 這隻對文檔的_id纔是真實的。

任何ObjectId您可能在文檔(或子文檔中)的其他字段中使用的其他位置不需要是唯一的,除非您創建的索引必須是唯一的。