【问题标题】:Use optional keys or a catch-all key in MongoMapper?在 MongoMapper 中使用可选键或包罗万象的键?
【发布时间】:2012-04-13 17:08:11
【问题描述】:

假设我正在开发一个如下所示的 MongoMapper 类:

class Animal
    include MongoMapper::Document

    key :type, String, :required => true
    key :color, String
    key :feet, Integer
end

现在我想存储一只鸟的翼展。加这个会不会比较好,虽然和很多文档无关,感觉有点不整洁:

    key :wingspan, Float

或者这个,即使它是一个难以描述的包罗万象,感觉就像一个黑客:

    key :metadata, Hash

看起来 :metadata 方法(在我继承的代码中有先例)对于整个 Mongo 文档来说几乎是多余的:它们都旨在成为键值对的无模式存储桶。

但是,添加动物专用键似乎也是一个非常难看的模型的滑坡。

任何替代方案(创建一个 Bird 子类)?

【问题讨论】:

    标签: mongodb schema database-schema mongomapper


    【解决方案1】:

    MongoMapper 不存储 nil 的键,因此如果您确实定义了 key :wingspan,则只有实际设置该键的文档会​​存储它。

    如果您选择不定义密钥,您仍然可以使用my_bird[:wingspan] = 23 设置/获取它。 ([] 调用实际上会自动为您定义一个键;类似地,如果从 MongoDB 返回的文档带有未明确定义的键,则将为它定义一个键,并且该类的所有文档 - 这是一种错误为整个班级定义它,但由于没有存储 nil 键,所以问题不大。)

    如果鸟也有自己的行为(它可能有),那么子类就有意义了。对于鸟类和动物,我会走这条路,因为每只鸟都是动物。对于Single Table/Single Collection 继承,MongoDB 比 ActiveRecord 好得多,因为您不需要十亿次迁移并且您的代码清楚地说明了哪些属性与哪些类一起使用。

    【讨论】:

    • 有趣 - 我只是玩了一下并确认确实存储和检索了未定义的键。那么,在模型中定义键有什么意义(除了设置默认值和 :required => true)?
    • 好吧,key 调用会调用 def my_attrdef my_attr=,所以你可以调用 bird.wingspan。对于未定义的键,key 在对象从数据库加载 之前不会被调用,因此如果您的应用程序很冷(例如测试),那么Bird.new.wingspan 将引发NoMethodError,因为key :wingspan还没有发生。
    【解决方案2】:

    如果不知道您将来打算如何扩展数据库以及您希望如何使用您存储的信息,就很难给出一个好的答案。如果您要存储大量鸟类并想总结翼展,那么翼展将很有帮助,即使它不会用于其他动物。如果您计划存储每个已知动物的随机任意信息,则尝试在模式中进行跟踪的可能性太多,而元数据方法会更有用。

    【讨论】:

      猜你喜欢
      • 2018-10-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-16
      • 2011-07-23
      • 2011-02-12
      • 2011-09-09
      • 1970-01-01
      相关资源
      最近更新 更多