Mustafa Yılmaz
Mustafa Yılmaz

Reputation: 245

MongoEngine recursive embedding

I am trying to model a document with mongoengine but I can't figure out how I can do recursive embedding. For example I want to do something like this

class NavigationHelper(EmbeddedDocument):
    name = StringField()
    url = URLField()
    sub_menus = EmbeddedDocumentListField(NavigationHelper)

I will use this to create a navigation tree with infinite sub-menu possibility. for example

-menu-1

--sub-menu-1-1

---sub-menu-1-1-1

---sub-menu-1-1-2

----sub-menu-1-1-2-1

-menu-2

is there any way for to model this? Thanks a lot.

Upvotes: 1

Views: 677

Answers (1)

Bruno Lubascher
Bruno Lubascher

Reputation: 2121

You can model that with one high level Document and a list of EmbeddedDocument.

from mongoengine import Document, EmbeddedDocument, StringField, URLField, EmbeddedDocumentListField

# The embeddedDocument of sub-menus
class NavigationSubMenu(EmbeddedDocument):
    name = StringField()
    url = URLField()
    sub_menus = EmbeddedDocumentListField('NavigationSubMenu')


# The document for the main menus
class NavigationMenu(Document):
    name = StringField()
    url = URLField()
    sub_menus = EmbeddedDocumentListField(NavigationSubMenu)

The example you gave would be created by:

docs = [
    NavigationMenu(name='1',
                   sub_menus=[
                       NavigationSubMenu(name='1-1',
                                         sub_menus=[
                                             NavigationSubMenu(name='1-1-1'),
                                             NavigationSubMenu(name='1-1-2',
                                                               sub_menus=[
                                                                   NavigationSubMenu(name='1-1-2-1')
                                                               ])
                                         ])
                   ]
                   ),
    NavigationMenu(name='2')
]

for doc in docs:
    doc.save()

docs = NavigationMenu.objects()

for doc in docs:
    print(doc.name)
    while len(doc.sub_menus) > 0:
        for sub_menu in doc.sub_menus:
            print(sub_menu.name)
            doc = sub_menu

>> 1
>> 1-1
>> 1-1-1
>> 1-1-2
>> 1-1-2-1
>> 2

If you save this, you will get 2 documents. One for each high level NavigationMenu.

Upvotes: 1

Related Questions