title: populate following users mongoose
body: <p>Lemme take time to explain what is happening from start to finish. </p>
  
  <p><strong>Preamble</strong>:</p>
  
  <p>A user a follows 10 other people. When user A logs in, an X number of posts from each of the 10 people are pulled into view.</p>
  
  <p>I do not know if it is the right thing to do, and will appreciate a better way of doing it. However, I wanna give it a try, and it ain't working.</p>
  
  <p><strong>Follow Model</strong>:</p>
  
  <pre><code>let mongoose = require('mongoose');
  let Schema = mongoose.Schema;
  
  let FollowSchema = new Schema({
    user: {
      type: Schema.Types.ObjectId,
      ref: 'User'
    },
    followers: [{
      type: Schema.Types.ObjectId,
      ref: 'Card'
    }],
    following: [{
      type: Schema.Types.ObjectId,
      ref: 'Card'
    }]
  });
  
  module.exports = mongoose.model('Follow', FollowSchema);
  </code></pre>
  
  <p><strong>Card Model</strong></p>
  
  <pre><code>let mongoose = require('mongoose');
  let Schema = mongoose.Schema;
  
  let CardSchema = new Schema({
    title: String,
    content: String,
    createdById: {
      type: Schema.Types.ObjectId,
      ref: 'User'
    },
    createdBy: {
      type: String
    }
  });
  
  module.exports = mongoose.model('Card', CardSchema);
  </code></pre>
  
  <p><strong>Follow logic</strong></p>
  
  <p>When user A follows user B, do two things:</p>
  
  <ul>
  <li>Push the user_id of B to user A document on field 'following' (A is following B)</li>
  <li><p>Push user_id of A to user B document on field 'followers' (B is followed by A) </p>
  
  <pre><code>router.post('/follow', utils.loginRequired, function(req, res) {
  const user_id = req.user._id;
  const follow = req.body.follow_id;
  
  let bulk = Follow.collection.initializeUnorderedBulkOp();
  
  bulk.find({ 'user': Types.ObjectId(user_id) }).upsert().updateOne({
      $addToSet: {
          following: Types.ObjectId(follow)
      }
  });
  
  bulk.find({ 'user': Types.ObjectId(follow) }).upsert().updateOne({
      $addToSet: {
          followers: Types.ObjectId(user_id)
      }
  })
  
  bulk.execute(function(err, doc) {
      if (err) {
          return res.json({
              'state': false,
              'msg': err
          })
      }
      res.json({
          'state': true,
          'msg': 'Followed'
      })
  })
  </code></pre>
  
  <p>})</p></li>
  </ul>
  
  <p><strong>Actual DB values</strong></p>
  
  <pre><code>&gt; db.follows.find().pretty()
  {
      "_id" : ObjectId("59e3e27dace1f14e0a70862d"),
      "user" : ObjectId("59e2194177cae833894c9956"),
      "following" : [
          ObjectId("59e3e618ace1f14e0a708713")
      ]
  }
  {
      "_id" : ObjectId("59e3e27dace1f14e0a70862e"),
      "user" : ObjectId("59e13b2dca5652efc4ca2cf5"),
      "followers" : [
          ObjectId("59e2194177cae833894c9956"),
          ObjectId("59e13b2d27cfed535928c0e7"),
          ObjectId("59e3e617149f0a3f1281e849")
      ]
  }
  {
      "_id" : ObjectId("59e3e71face1f14e0a708770"),
      "user" : ObjectId("59e13b2d27cfed535928c0e7"),
      "following" : [
          ObjectId("59e3e618ace1f14e0a708713"),
          ObjectId("59e13b2dca5652efc4ca2cf5"),
          ObjectId("59e21942ca5652efc4ca30ab")
      ]
  }
  {
      "_id" : ObjectId("59e3e71face1f14e0a708771"),
      "user" : ObjectId("59e3e618ace1f14e0a708713"),
      "followers" : [
          ObjectId("59e13b2d27cfed535928c0e7"),
          ObjectId("59e2194177cae833894c9956")
      ]
  }
  {
      "_id" : ObjectId("59e3e72bace1f14e0a708779"),
      "user" : ObjectId("59e21942ca5652efc4ca30ab"),
      "followers" : [
          ObjectId("59e13b2d27cfed535928c0e7"),
          ObjectId("59e2194177cae833894c9956"),
          ObjectId("59e3e617149f0a3f1281e849")
      ]
  }
  {
      "_id" : ObjectId("59f0eef155ee5a5897e1a66d"),
      "user" : ObjectId("59e3e617149f0a3f1281e849"),
      "following" : [
          ObjectId("59e21942ca5652efc4ca30ab"),
          ObjectId("59e13b2dca5652efc4ca2cf5")
      ]
  }
  &gt; 
  </code></pre>
  
  <p>With the above database results, this is my query:</p>
  
  <p><strong>Query</strong></p>
  
  <pre><code>router.get('/follow/list', utils.loginRequired, function(req, res) {
      const user_id = req.user._id;
  
      Follow.findOne({ 'user': Types.ObjectId(user_id) })
        .populate('following')
        .exec(function(err, doc) {
            if (err) {
                return res.json({
                    'state': false,
                    'msg': err
                })
            };
  
            console.log(doc.username);
  
            res.json({
                'state': true,
                'msg': 'Follow list',
                'doc': doc
            })
        })
  });
  </code></pre>
  
  <p>With the above query, from my little understanding of Mongoose populate, I expect to get cards from each of the Users in the <code>following</code> array.</p>
  
  <p>My understanding and expectations might be wrong, however with such an endgoal, is this populate approach okay? Or am I trying to solve an aggregation task with population?</p>
  
  <p><strong>UPDATE:</strong></p>
  
  <p>Thanks for the answer. Getting quite close, but still, the <code>followingCards</code> array contains no result. Here's the contents of my current <code>Follow</code> model:</p>
  
  <pre><code>&gt; db.follows.find().pretty()
  {
      "_id" : ObjectId("59f24c0555ee5a5897e1b23d"),
      "user" : ObjectId("59f24bda1d048d1edad4bda8"),
      "following" : [
          ObjectId("59f24b3a55ee5a5897e1b1ec"),
          ObjectId("59f24bda55ee5a5897e1b22c")
      ]
  }
  {
      "_id" : ObjectId("59f24c0555ee5a5897e1b23e"),
      "user" : ObjectId("59f24b3a55ee5a5897e1b1ec"),
      "followers" : [
          ObjectId("59f24bda1d048d1edad4bda8")
      ]
  }
  {
      "_id" : ObjectId("59f24c8855ee5a5897e1b292"),
      "user" : ObjectId("59f24bda55ee5a5897e1b22c"),
      "followers" : [
          ObjectId("59f24bda1d048d1edad4bda8")
      ]
  }
  &gt;
  </code></pre>
  
  <p>Here are all the current content I have from <code>Card</code> Model:</p>
  
  <pre><code>&gt; db.cards.find().pretty()
  {
      "_id" : ObjectId("59f24bc01d048d1edad4bda6"),
      "title" : "A day or two with Hubtel's HTTP API",
      "content" : "a day or two",
      "external" : "",
      "slug" : "a-day-or-two-with-hubtels-http-api-df77056d",
      "createdBy" : "seanmavley",
      "createdById" : ObjectId("59f24b391d048d1edad4bda5"),
      "createdAt" : ISODate("2017-10-26T20:55:28.293Z"),
      "__v" : 0
  }
  {
      "_id" : ObjectId("59f24c5f1d048d1edad4bda9"),
      "title" : "US couple stole goods worth $1.2m from Amazon",
      "content" : "for what",
      "external" : "https://bbc.com",
      "slug" : "us-couple-stole-goods-worth-dollar12m-from-amazon-49b0a524",
      "createdBy" : "nkansahrexford",
      "createdById" : ObjectId("59f24bda1d048d1edad4bda8"),
      "createdAt" : ISODate("2017-10-26T20:58:07.793Z"),
      "__v" : 0
  }
  </code></pre>
  
  <p>With the Populate Virtual example from yours (@Veeram), here's the response I get:</p>
  
  <pre><code>{"state":true,"msg":"Follow list","doc":{"_id":"59f24c0555ee5a5897e1b23d","user":"59f24bda1d048d1edad4bda8","following":["59f24b3a55ee5a5897e1b1ec","59f24bda55ee5a5897e1b22c"],"followers":[],"id":"59f24c0555ee5a5897e1b23d","followingCards":[]}}
  </code></pre>
  
  <p>The <code>followingCards</code> array is empty.</p>
  
  <p>Using the <code>$lookup</code> query on the other hand simply returns <code>[]</code></p>
  
  <p>I'm likely missing something?</p>