Wie ein eingebettetes Dokument in Mongoid verweisen?
Frage
Mit Mongoid, lassen Sie uns sagen, dass ich die folgenden Klassen:
class Map
include Mongoid::Document
embeds_many :locations
end
class Location
include Mongoid::Document
field :x_coord, :type => Integer
field :y_coord, :type => Integer
embedded_in :map, :inverse_of => :locations
end
class Player
include Mongoid::Document
references_one :location
end
Wie Sie sehen können, ich versuche, eine einfache Spielwelt Umgebung zu modellieren, wo eine Karte Orte einbettet, und einem Spieler Referenz einen einzigen Ort als ihren aktuellen Ort.
Mit diesem Ansatz, erhalte ich die folgende Fehlermeldung, wenn ich versuche, das „location“ Attribut der Klasse Spieler zu verweisen:
Mongoid::Errors::DocumentNotFound: Document not found for class Location with id(s) xxxxxxxxxxxxxxxxxxx.
Mein Verständnis ist, dass dies, weil die Location-Dokument eingebettet ist, so dass es nicht in den Anwendungsbereich seiner Einbettung Dokument Bezug schwierig (die Karte). Dies macht Sinn, aber wie kann ich einen direkten Verweis auf ein eingebettetes Dokument modellieren?
Lösung
Weil Karten ihre eigene Sammlung sind, möchten Sie Iterierte müssen über jede Kartensammlung Suche innerhalb der Lage ihren Spieler verwiesen wird.
Sie können den Zugriff nicht-Dokumente eingebettet direkt. Sie haben durch die Sammlung geben und arbeiten Sie sich nach unten.
Um zu vermeiden, alle Karten Iterieren Sie sowohl den Ort Bezug und die Karte Referenz in Ihrem Spieler Dokument speichern. So können Sie Ketten Kriterien, die Ihre Karte und dann die Lage innerhalb wählt. Sie haben eine Methode auf ihren Spieler Klasse Code zu handhaben.
def location
self.map.locations.find(self.location_id)
end
So ähnlich, wie Sie selbst beantwortet, außer Sie immer noch die location_id in Ihrem Player Dokument speichern könnten stattdessen die coord attribs zu verwenden.
Eine andere Möglichkeit wäre, Karten zu setzen, Standorte und Spieler in ihren eigenen Sammlungen statt den Standort in Ihrer Kartensammlung integrieren. Dann könnten Sie Referenzbeziehungen verwenden, ohne etwas Besonderes zu tun ... aber Ihnen wirklich nur eine hierarchische Datenbank mag, es ist eine relationale Datenbank an dieser Stelle ...
Andere Tipps
Bitte gehen und Stimme für die „virtuelle Sammlungen“ -Funktion auf MongoDB der issue tracker:
http://jira.mongodb.org/browse/SERVER-142
Es ist die zweite am meisten nachgefragte Funktion, aber es hat sich noch nicht für die Freigabe geplant. wenn genug Leute für ihn stimmen vielleicht und bewegen sie die Nummer eins, wird die MongoDB Team endlich umzusetzen.
In meinem Anwendungsfall gibt es keine Notwendigkeit für das Außen Objekt des eingebettete Dokument zu verweisen. Von der mongoid Benutzergruppe, fand ich die Lösung. Verwenden referenced_in auf dem eingebettete Dokument und NO Verweis auf der Außenseite Dokument
class Page
include Mongoid::Document
field :title
embeds_many :page_objects
end
class PageObject
include Mongoid::Document
field :type
embedded_in :page, :inverse_of => :page_objects
referenced_in :sprite
end
class Sprite
include Mongoid::Document
field :path, :default => "/images/something.png"
end
header_sprite = Sprite.create(:path => "/images/header.png")
picture_sprte = Sprite.create(:path => "/images/picture.png")
p = Page.create(:title => "Home")
p.page_objects.create(:type => "header", :sprite => header_sprite)
p.page_objects.first.sprite == header_sprite
Meine aktuelle Lösung ist folgendes zu tun:
class Map
include Mongoid::Document
embeds_many :locations
references_many :players, :inverse_of => :map
end
class Player
referenced_in :map
field :x_coord
field :y_coord
def location=(loc)
loc.map.users << self
self.x_coord = loc.x_coord
self.y_coord = loc.y_coord
self.save!
end
def location
self.map.locations.where(:x_coord => self.x_coord).and(:y_coord => self.y_coord).first
end
end
Das funktioniert, aber man fühlt sich wie ein Kluges.
Denken außerhalb der Box, können Sie Lage sein eigenes Dokument erstellen und verwenden Mongoid Alize automatisch eingebettete Daten in Ihrem Map Dokument von Ihren Standort-Dokumenten zu erzeugen.
https://github.com/dzello/mongoid_alize
Der Vorteil dieser Methode ist, dass Sie effiziente Abfragen erhalten, wenn die Bedingungen geeignet sind und langsame Referenz basierte Abfragen auf dem Originaldokument, wenn es keine andere Möglichkeit gibt.