I want to port a social network to Mongoid. The join table between friends is very large. Is there any way for Mongoid to handle this join table out of the box? I've seen a couple of in-model roll-your-own solutions to it, but nothing the looks efficient. Is there a way to handle this? Or is this a case where I shouldn't be using Mongoid?
Many-to-many should be avoid for scale applications. What Twitter for example does is that it store the followers ids in comma seperated format (string) inside the user object. Using MongoDB is even better as it supports arrays.
Remember that what describes best NoSQL is the term NoJoin ;-)
You can create many-to-many (polymorphic) associations by using relational associations and store the relation as an array.
class Person
include Mongoid::Document
field :name
references_many :preferences, :stored_as => :array, :inverse_of => :people
end
class Preference
include Mongoid::Document
field :name
references_many :people, :stored_as => :array, :inverse_of => :preferences
end
ps1 = Person.create(:name => 'John Doe')
pf1 = Preference.create(:name => 'Preference A')
pf2 = Preference.create(:name => 'Preference B')
ps1.preferences << pf1
ps1.preferences << pf2
ps1.save
pf1.people.each {|ps| puts ps.name }
ps1.preferences.each {|pf| puts pf.name }
More about relational associations can be found in the Mongoid documentation: http://mongoid.org/docs/associations/
Note: references_many stored as arrays can be staggering slow on mass creating/updating objects with many relations. A more traditional RDBMS will easily outperform Mongo because it will add a new row for each relation, where mongo needs to retrieve and update the object_ids array for the object itself and for each relation.
this method is deprecated. you can now use references_and_referenced_in_many like so:
class Person
include Mongoid::Document
field :name
references_and referenced_in_many :preferences
end
class Preference
include Mongoid::Document
field :name
references_and referenced_in_many :people
end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With