我想将社交网络移植到 Mongoid。朋友之间的联接表非常大。Mongoid 有什么方法可以开箱即用地处理这个连接表吗?我已经看到了几个模型内自行滚动的解决方案,但看起来没有任何效率。有没有办法处理这个?或者这是我不应该使用 Mongoid 的情况?
4 回答
对于规模应用,应避免多对多。例如,Twitter 所做的是将关注者 ID 以逗号分隔格式(字符串)存储在用户对象中。使用 MongoDB 会更好,因为它支持数组。
请记住,描述最佳 NoSQL 的是术语 NoJoin ;-)
您可以使用关系关联创建多对多(多态)关联,并将关系存储为数组。
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 }
有关关系关联的更多信息可以在 Mongoid 文档中找到: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
你不用 MongoDB 做多对多的关系和连接表。每个用户都将他们的整个朋友图存储在实际的用户对象上,以及其他所有内容,如偏好、图片(GridFS)等。如果您需要做需要关系代数的特殊事情,只需使用 RDBMS,否则 MongoDB 将工作好。可以进行高级查询,但必须使用 mapreduce。