title: MongoDB one-to-many - array of IDs or ID ref on child model?
body: <p>Specifically, I'm thinking of a chat app, where a <code>User</code> has many <code>Chat</code>s and each <code>Chat</code> has many <code>Message</code>s. How would I express the <code>Chat --has-Many--&gt; Message</code> relationship?</p>
  
  <p>Initially, I thought I'd store the list of <code>Message</code> ID references on <code>Chat</code>, e.g. a <code>Chat</code> document could look something like</p>
  
  <pre><code>{
    _id: ObjectId('507f191e810c19729de860d5'),
    title: 'Jack V, Kyle R, Sam P',
    messages: [ObjectId('507f191e810c19729de860ea'), ...],
    createdAt: 1546284204867
  }
  </code></pre>
  
  <p>This way, I'd need to <code>$push</code> to the array every time a message is sent, or <code>$pull</code> if it's deleted. Makes the code somewhat more complex and obscure, but still doable.</p>
  
  <p>Then I read from <a href="https://docs.mongodb.com/manual/tutorial/model-referenced-one-to-many-relationships-between-documents/" rel="nofollow noreferrer">MongoDB docs</a> that this approach is only tenable when the array is <em>small</em> and has a <em>limited growth</em>. <em>To avoid mutable, growing arrays</em>, it's better that <code>Message</code> retains a <code>chatId</code> ref back to its parent <code>Chat</code></p>
  
  <pre><code>{
    _id: ObjectId('507f191e810c19729de860ea'),
    body: 'Hey Kyle! Mind if I ask ya a favor?',
    chatId: ObjectId('507f191e810c19729de860d5'),
    createdAt: 1546284204869
  }
  </code></pre>
  
  <p>In the end, if I want to fetch messages for a chat with Mongoose,</p>
  
  <pre><code>const chatId = '507f191e810c19729de860d5'
  
  // 1. through IDs array
  Chat.findById(chatId).populate('messages').execPopulate()
  
  // or
  
  // 2. through ID ref
  Message.find({ chatId })
  </code></pre>
  
  <p>From my understanding,</p>
  
  <ul>
  <li>1st is more efficient, b/c it takes an array of IDs and quickly locates the <code>Message</code> documents, and <em>only then</em> reads them</li>
  <li>2nd is less efficient, b/c it <em>has</em> to read <em>all</em> <code>Message</code> documents (potentially, millions) and compare <code>chatId</code> attribute on each</li>
  </ul>
  
  <p>This in keeping with the fact that <em>reads</em> are much more expensive in MongoDB than <em>writes</em>. Am I correct is asserting that? If so, why are most resources recommending approach #2? I see it in <a href="https://developer.mozilla.org/en-US/docs/Learn/Server-side/Express_Nodejs/mongoose#Working_with_related_documents_%E2%80%94_population" rel="nofollow noreferrer">MDN docs</a> (see yellow box), in <em>50 Tips and Tricks for MongoDB Developers</em>, and in MongoDB docs.</p>
  
  <p>With one-to-many relationships, is it better to maintain an array of IDs on parent model, or rather have an ID ref on each child model?</p>