代码之家  ›  专栏  ›  技术社区  ›  Garrett

何时使用嵌入文档?

  •  4
  • Garrett  · 技术社区  · 15 年前

    我正在尝试为我正在工作的站点设计数据库的布局。以下是我的模型:

    class User
      include MongoMapper::Document
    
      // keys here
    
      many :items
      many :likes
    end
    
    class Item
      include MongoMapper::Document
    
      key :name, String, :required => true
    
      many :likes
    end
    
    class Like
      include MongoMapper::EmbeddedDocument
    
      key :user_id, String, :required => true
    end
    

    我相信 Like 应该嵌入到某个地方,但是由于我想从中获得的功能,我很难选择一个。

    user = User.first
    user.likes // should print out all the Items he liked
    
    item = Item.first
    item.likes // so I can count how many people like that item
    

    虽然在使用嵌入文档时会出现问题,但是您会丢失 find 和其他有用的方法,不能将其嵌入这两个模型中。所以只有在 Item ,我需要运行此(但无法运行):

    item = Item.first
    item.likes.find_by_user_id(User.first._id)
    

    未定义的方法 find_by_user_id 将被抛出。所以如果我把这个嵌入到我的 User 我还是做不到。

    likes = Like.all // will throw undefined `all`
    

    所以我得出结论,也许这样做:

    class Like
      include MongoMapper::Document
    
      key :user_id, String, :required => true
      key :item_id, String, :required => true
    
      belongs_to :user
      belongs_to :item
    end
    

    但我似乎仍在用老的MySQL方式做事情。有人能给我一点关于用MongoMapper编写代码的可能性最大的方法吗?

    事先谢谢!

    2 回复  |  直到 14 年前
        1
  •  9
  •   Emily    15 年前

    是否可以在MongoMapper中对此进行建模取决于是否有数据需要存储在 Like 模型。如果没有任何数据与 喜欢 模特儿,有办法。最近对MongoMapper的更新增加了对多对多关系的支持,尽管它还处于早期阶段。

    您可以这样创建模型:

    class User
      include MongoMapper::Document
      key :name, String, :required => true
      key :liked_item_ids, Array
      many :liked_items, :in => :liked_item_ids, :class_name => "Item"
    end
    
    class Item
      include MongoMapper::Document
      key :name, String, :required => true
      many :fans, :class_name => "User", :foreign_key => :liked_item_ids
    end
    

    然后你可以做:

    >> u = User.new( :name => 'emily' )
    >> i = Item.new( :name => 'chocolate' )
    >> u.liked_items << i
    >> u.save
    >> u.liked_items
    => [#<Item name: "chocolate", _id: 4b44cc6c271a466269000001>]
    
    >> i.fans
    => [#<User name: "emily", liked_item_ids: [4b44cc6c271a466269000001], _id: 4b44cc6c271a466269000002>]
    

    不幸的是,您无法使用此安装程序从 Item 关系的另一面。然而,关于为 many :in 在这种情况下,将使用的关系如下:

    many :fans, :class_name => "User", :source => :liked_items
    

    另一方面,如果需要在 喜欢 例如用户喜欢该项目的日期,目前没有建模方法。在这种情况下,理想的设置(忽略MongoMapper现在支持的内容)将类似于问题中包含的内容。你需要这三种型号 喜欢 嵌入在 User 模型与A has_many :through 创建链接的关系 用户 项目 . 不幸的是,在MongoMapper中对此的支持可能非常遥远。

    如果您想鼓励支持MongoMapper中的这种行为,可以在 mailing list 或者打开一个问题 MongoMapper github repository .

        2
  •  3
  •   railsmongo    14 年前

    您可能需要阅读mongodb.org上的文档“嵌入vs.引用”: http://www.mongodb.org/display/DOCS/Schema+Design#SchemaDesign-Embedvs.Reference

    推荐文章