Skip to content

Instantly share code, notes, and snippets.

@bagerard
Last active July 26, 2021 11:20
Show Gist options
  • Select an option

  • Save bagerard/a7dc0b63dcfcfa1d48ff509774270d28 to your computer and use it in GitHub Desktop.

Select an option

Save bagerard/a7dc0b63dcfcfa1d48ff509774270d28 to your computer and use it in GitHub Desktop.
Mongoengine snippet related to https://stackoverflow.com/q/56609288/6203472
from mongoengine import connect, Document, EmbeddedDocument, \
ReferenceField, EmbeddedDocumentListField, StringField, ObjectIdField
connect() # Connect to `test` database by default
######
# Option1: Using 2 different collections for users and tickets
######
class User(Document):
name = StringField()
role = StringField()
def get_tickets(self):
return Ticket.objects(assignee=self)
class Ticket(Document):
assignee = ReferenceField(User)
content = StringField()
# Load some sample data
us1 = User(name='John', role='admin')us2 = User(name='Bob', role='guest').save()
us1.save()
Ticket(assignee=us1, content='Lorem Ipsum').save()
Ticket(assignee=us1, content='whatever').save()
Ticket(assignee=us2, content='blablabla').save()
admin_users = User.objects(role='admin')
admin_users_tickets = Ticket.objects(assignee__in=admin_users)
for ticket in admin_users_tickets:
print(ticket.content, ticket.assignee.name, ticket.assignee.id)
# prints:
#(u'Lorem Ipsum', u'John', ObjectId('5d04dcb119dca50d61906f19'))
#(u'whatever', u'John', ObjectId('5d04dcb119dca50d61906f19'))
######
# Option2: Using 1 single collection and embedding the tickets in each user
######
class EmbedTicket(EmbeddedDocument):
content = StringField()
class NewUser(Document):
name = StringField()
role = StringField()
tickets = EmbeddedDocumentListField(EmbedTicket)
# Load sample data
NewUser(name='Malcolm', role='admin', tickets=[EmbedTicket(content='whatever1'), EmbedTicket(content='whatever2')]).save()
NewUser(name='Ulrich', role='guest', tickets=[EmbedTicket(content='whatever99')]).save()
tickets_per_admin_user = {} # mapping {user_id: ticket}
for user in NewUser.objects(role='admin'):
tickets_per_admin_user[str(user.id)] = user.tickets
print(tickets_per_admin_user)
# prints
# {'5d04dfee19dca50d61906f1e': [<EmbedTicket: EmbedTicket object>, <EmbedTicket: EmbedTicket object>]}
######
# Option3: same as Option2 but keeping the user_id inside the embedded tickets
# Not the one I'd recommend as it duplicates the information and isn't very handy to manipulate
######
class EmbedTicket2(EmbeddedDocument):
content = StringField()
user_id = ObjectIdField(required=True)
class NewUser2(Document):
name = StringField()
role = StringField()
tickets = EmbeddedDocumentListField(EmbedTicket2)
us = NewUser2(name='X', role='admin').save()
us.tickets = [EmbedTicket2(content='blabla', user_id=us.id)]
us.save()
@bagerard
Copy link
Copy Markdown
Author

You are welcome, I'm happy to help

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment