2011-04-20 39 views
1

用mongoid和Rails去規範化的最好方法是什麼?用mongoid反規格化

使用「嵌入式」關係似乎不起作用(或僅用於嵌入整個原始文檔)。

我現在的解決方案商店和檢索非規範化的屬性作爲OrderedHash:

collection.update({_id: id, ...}, {..., denormalized: {_id: other.id, _type: other._type, a: other.a, b: other.b}} 

def denormalized 
    Mongoid::Factory.build(attributes[:denormalized]["_type"], attributes[:denormalized]) 
end 

編輯:我要指出,我沒有嘗試https://github.com/logandk/mongoid_denormalize

它變平的非規範化的屬性(在本例下面,它將存儲author_name而不是author:{name:「value」},它不支持多個非規範化關係(例如authors:[{name:「First Co-Author」,_id:1},{name :「Second Co-Author」,_id:2}])

編輯:請求了一個例子。

class User # this class uses STI so _type field is important 
    include Mongoid::Document 

    field :name # this is the field I want to de-normalize to where Users are referenced 

    def write_book 
    Book.create!({title: "Some Text", author: {_id: self.id, _type: self._type, name: self.name}) 
    end 
end 

class Book 
    include Mongoid::Document 

    field :title 

    # embeds_one :author, polymorphic: true 
    # tried this but it doesn't seem to be correct usage... it sort of works but 
    # I run into problems with cycles and infinite loops when used extensively 
    # because (I think) of how mongoid works internally, expecting embeds_one 
    # to mean something different 

    def author 
    Mongoid::Factory.build(attributes[:author]["_type"], attributes[:author]) 
    end 
end 

正確的解決方案會有ActiveModel方法,如new_record?工作以及* _path和* _url路由助手。

+1

你可以添加一個例子,你想反規範化? – Voldy 2011-04-20 19:32:40

+0

編輯原文,以提供示例 – Jason 2011-04-20 19:44:15

+0

另一個例子(摘自MongoDB in Action,第62頁)將是電子商務訂單。您會將運送地址和物品/價格歸一化。那在Mongoid中如何實現? – Raphael 2012-03-21 23:08:43

回答

-1

這會將用戶存儲爲書中的嵌入式作者文檔。

class User 
    include Mongoid::Document 
end 

#instead of the write book method, you could just do this: 
book = Book.create(title: "Old Man And The Sea", users: [user]) 

class Book 
    include Mongoid::Document 

    embeds_many :authors 

    field :title 

    def users=(users) 
    users.each do |user| 
     authors.build(user: user, name: user.name) 
    end 
    end 
end 

class Author 
    include Mongoid::Document 

    embedded_in :book 
    referenced_in :user 

    field :name 
end 
+0

我沒有看到用戶的名字將被非規範化到書本文檔中。 – Jason 2011-04-20 22:06:46

+0

這不是反規範化。 – Raphael 2012-03-21 23:06:37