Skip to content

Instantly share code, notes, and snippets.

@bagerard
Last active July 26, 2021 11:20
Show Gist options
  • Save bagerard/a7dc0b63dcfcfa1d48ff509774270d28 to your computer and use it in GitHub Desktop.
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
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