Mongoid的store_in方法产生随机结果

5

我正在使用Rails 3.2.2和Mongoid 2.4.6。为了保持我的集合小,我使用"store_in"语句将子对象存储到基类的不同集合中。我的代码如下:

class BaseClass
  include Mongoid::Document
end

class ChildClass1 < BaseClass
  store_in :child_1
end  

class ChildClass2 < BaseClass
  store_in :child_2
end

看起来对象随机存储在两个子集合中的一个中。Child1类型的对象有时会存储在Child2集合中。这是我在日志中看到的惊人之处:

Started POST "/child_class_1" for 127.0.0.1 at 2012-05-22 10:22:51 -0400
Processing by ChildClass1Controller#create as HTML

MONGODB (0ms) myproject_development['child_2'].insert....

这是从哪里来的?这是mongoid、rails还是mongodb中的一个bug吗?


你尝试过更新到最新版本的Mongoid吗?我相信它目前是2.4.10。 - theTRON
1个回答

10

我花了一些时间才弄清楚答案,我决定发表它,希望能帮助其他人。

Mongoid实现了所谓的“单表继承”。只要您从父类派生一个子类,该子类就会被存储在父集合中并添加一个“type”属性。使用“store_in”方法可以显式地告诉mongodb将文档存储在哪个集合中。在子类中定义“store_in”将使mongoid将所有内容(包括父级)存储在指定的集合中。我猜想为每个子类分配专门的“store_in”可能会导致mongoid出错。然而,结果是文档随机存储在任何给定的集合中。

可以通过在Ruby中使用模块作为共同功能的mixin来解决这个问题。这在这篇文章中描述得很好。

但最终我决定不这样做!我之所以想要这样做,是为了保持我的集合小,希望获得更好的性能。在与一些(10gen)专家交谈后,我认为更好的方法是将所有子元素都存储在单个父对象集合中。这不应该对mongodb的性能产生影响,但解决方案变得更加灵活。事实上,这更好地利用了mongodb的无模式设计。

所以代码将再次如下所示:

class BaseClass
  include Mongoid::Document

  ... shared functionality

end

class ChildClass1 < BaseClass
  ...individual functionality...
end  

class ChildClass2 < BaseClass
  ...individual functionality...
end

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接