2014-11-18 12 views
8

Ich modelliere eine MongoBD-Datenbank in MongoEngine für ein Webprojekt. Ich möchte die Daten auf eine etwas ungewöhnliche Weise speichern, um sie später effizient abfragen zu können.MongoEngine: Speichern von EmbeddedDocument in DictField

Unsere Daten in MongoDB etwa wie folgt aussehen:

class Inner(EmbeddedDocument): 
    name = StringField() 

class Outer(Document): 
    outer_data = StringField() 
    embed = DictField(EmbeddedDocument(Inner)) # this isn't allowed but you get the point 

Mit anderen Worten, was ich im Wesentlichen will, ist das gleiche:

// "outer" 
{ 
    "outer_data": "directors", 
    "embed": { 
    "some_md5_key": { "name": "P.T. Anderson" }, 
    "another_md5_key": { "name": "T. Malick" }, 
    ... 
    } 
} 

Mein erster Instinkt es so in MongoEngine zu modellieren war Speichern eines EmbeddedDocuments in einem ListField, jedoch in einem DictField mit dynamischen Schlüsseln für jedes EmbeddedDocument.

Beispiel, dass wird mit einem Listfield Referenz erlaubt:

class Inner(EmbeddedDocument): 
    inner_id = StringField(unique=True) # this replaces the dict keys 
    name = StringField() 

class Outer(Document): 
    outer_data = StringField() 
    embed = ListField(EmbeddedDocument(Inner)) 

Ich würde es vorziehen MongoEngine Objekte zurückgegeben auch für die verschachtelten „Inner“ Dokumente zu haben, während immer noch einen DictField + EmbeddedDocument (wie dict mit " Wert"). Wie kann ich dies in MongoEngine modellieren? Ist es überhaupt möglich oder muss ich naiv alle Daten unter ein generisches DictField legen?

Antwort

14

Ich fand endlich die Antwort auf mein Problem. Der richtige Weg, um dieses Muster zu erreichen, ist die Verwendung eines MapField.

Das entsprechende Modell in MongoEngine wie folgt aussieht:

class Inner(EmbeddedDocument): 
    name = StringField() 

class Outer(Document): 
    outer_data = StringField() 
    embed = MapField(EmbeddedDocumentField(Inner)) 

In MongoDB, alle Schlüssel brauchen Saiten zu sein, so dass keine Notwendigkeit besteht, einen „Feldtyp“ für die Schlüssel in den MapField angeben.

+2

Ich versuchte diesen Ansatz, aber beim Speichern gibt es mir "Das Quelle SON-Objekt muss vom Typ 'dict' sein". Haben Sie eine Lösung dafür wird sehr hilfreich sein. Vielen Dank – ptwo

Verwandte Themen