mongodb _id删除后重用

时间:2013-10-08 13:11:35

标签: ruby-on-rails ruby mongodb mongoid

假设我删除了mongodb中的文档或子文档。我可以使用与已删除的_id相同的_id创建文档/子文档吗?在这种情况下,我们假设,我们不能做更新操作,只需删除并创建。

例如使用Mongoid(Rails gem for 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
    ...
    @the_attributes=@person.personattributes.entries
    ... 
    #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,因为删除的文档需要另外一个循环来处理。

谢谢

2 个答案:

答案 0 :(得分: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

可能在将来您想要更改操作并仅在数组中发送修改后的personattributes而不是所有personattributes。如果你只使用发送的personattributes delete_all并重建personattributes,你会怎么做?

修改

这会处理personattributes更新。创建或删除personattributes应该采取不同的行动:

制作行动

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

删除操作

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

答案 1 :(得分:0)

是的,您可以继续使用相同的_id。它们只需要在集合中是唯一的 - 而且只有文档的_id才是唯一的。

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