title: MongoDB : How to design schema based on application access patterns?
body: <p>As someone that comes from DynamoDB, modeling a MongoDB schema to really fit deeply into my application is kinda confusing, specially since it has the concept of references and from what I read is not recommended to keep duplicated data to accomodate your queries.</p>
  
  <p>Take the following example (modeled in mongoengine, but shouldn't matter) :</p>
  
  <pre class="lang-py prettyprint-override"><code>    #User
      class User(Document):
          email = EmailFieldprimary_key=True)
          pswd_hash = StringField()
          #This also makes it easier to find the Projects the user has a Role
          roles = ListField(ReferenceField('Role')
  
      #Project
      class Project(Document):
          name = StringField()
          #This is probably unnecessary as the Role id is already the project id
          roles = ListField(ReferenceField('Role'))
  
      #Roles in project
      class Role(Document):
          project = ReferenceField('Project', primary_key=True)
          #List of permissions
          permissions = ListField(StringField())
          users = ListField(ReferenceField('User')
  </code></pre>
  
  <p>There are <strong>Projects</strong> and <strong>Users</strong>.</p>
  
  <p>Each <strong>Project</strong> can have many <strong>Roles</strong> in it.</p>
  
  <p>Each <strong>User</strong> can have one <strong>Role</strong> in a <strong>Project</strong>.</p>
  
  <hr>
  
  <p>So, it's a Many-Many between <strong>Users</strong> and <strong>Projects</strong></p>
  
  <p>A Many-One between <strong>Users</strong> and <strong>Roles</strong></p>
  
  <p>A Many-One between <strong>Roles</strong> and <strong>Projects</strong></p>
  
  <hr>
  
  <p>The problem is when I try to accomodate the schema to the access, because on every page refresh on the application, I need :</p>
  
  <ol>
  <li>Project (the id is in the url)</li>
  <li>User (email is in session)</li>
  <li>User permissions in that project (server-side security checks)</li>
  </ol>
  
  <p>So, considering this is the most common query, how should I model my schema to accomodate it? </p>
  
  <p>Or is the way I'm doing at the moment okay already?</p>