MongoEngine: хранение EmbeddedDocument в DictField

Я моделирую базу данных MongoDB в MongoEngine для веб-проекта. Я хочу хранить данные несколько необычным способом, чтобы иметь возможность эффективно запрашивать их позже.

Наши данные в MongoDB выглядят примерно так:

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

Моим первым побуждением было смоделировать это в MongoEngine вот так:

class Inner(EmbeddedDocument):
  name = StringField()

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

Другими словами, то, что я, по сути, хочу, это то же самое, что и хранение EmbeddedDocument в ListField, а скорее в DictField с динамическими ключами для каждого EmbeddedDocument.

Пример того, что разрешено с ListField для справки:

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))

Я бы предпочел, чтобы объекты MongoEngine возвращались также для вложенных «внутренних» документов, все еще используя DictField + EmbeddedDocument (как dict «value»). Как я могу смоделировать это в MongoEngine? Возможно ли это вообще, или я должен наивно размещать все данные в общем поле DictField?


person robinandeer    schedule 18.11.2014    source источник


Ответы (1)


Я наконец нашел ответ на свою проблему. Правильный способ добиться этого шаблона - использовать MapField.

Соответствующая модель в MongoEngine выглядит так:

class Inner(EmbeddedDocument):
  name = StringField()

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

В MongoDB все ключи должны быть строками, поэтому нет необходимости указывать «тип поля» для ключей в MapField.

person robinandeer    schedule 19.11.2014
comment
Я пробовал этот подход, но при сохранении он дает мне Исходный объект SON должен иметь тип 'dict'. У вас есть решение для этого, будет очень полезно. Спасибо - person ptwo; 18.04.2017
comment
для меня embed был списком словарей. итак, embed = ListField(EmbeddedDocumentField(Inner)) работал у меня - person Sridhar; 13.08.2018