Stack Exchange
Find documents based on a Reference to the Parent in the Child with Pagination
There are  2 collections Movie and Rank Movie .This 2 collections having referenced relationship .
Movie model
var mongoose = require('mongoose');

var movieSchema = new mongoose.Schema({
    m_tmdb_id: {
        type: Number,
        unique: true,
        index: true
    },
    m_adult: {
        type: Boolean
    },
    m_backdrop_path: {
        type: String,
    },
    m_title: {
        type: Number
    },
    m_genres: {
        type: Array
    }

});
var MovieModel = mongoose.model('Movie', movieSchema);
module.exports = {
    movie: MovieModel
}

Rank movie model
var mongoose = require('mongoose');
var rankMovieSchema = new mongoose.Schema({
    movie: {
        type: mongoose.Schema.Types.ObjectId,
        ref: 'Movie',
        unique: true
    },
    rank: {
        type: Number
    },
    count: {
        type: Number
    }
});
var RankMovieModel = mongoose.model('RankMovie', rankMovieSchema);
module.exports = {
    rankmovie: RankMovieModel
}

I need to select all the top 10 items in each query [Pagination] from the collection rank movie having a particular m_genres name[Condition on movie collection ].
Ex:
Movie collection
[{
    "_id": ObjectId("5930ea4806fb9e365e0d55b5"),
    "m_tmdb_id": 888724,
    "m_imdb_id": "sd2806",
    "m_title": "Mechanic: Resurrection",
    "m_genres": [{
        "name": "Action",
        "id": 28
    }, {
        "name": "Crime",
        "id": 80
    }, {
        "name": "Thriller",
        "id": 53
    }]
}, {
    "_id": ObjectId("583e3bd69e2ea90c69c5a254"),
    "m_tmdb_id": 23924,
    "m_imdb_id": "tt3d2806",
    "m_title": "Inter",
    "m_genres": [{
        "name": "Drama",
        "id": 32
    }, {
        "name": "Crime",
        "id": 80
    }]
}, {
    "_id": ObjectId("5930eaa706fb9e365e0d55c8"),
    "m_tmdb_id": 378924,
    "m_imdb_id": "sdstt3522806",
    "m_title": "Spiderman",
    "m_genres": [{
        "name": "Action",
        "id": 28
    }, {
        "name": "Crime",
        "id": 80
    }, {
        "name": "Thriller",
        "id": 53
    }]
}]

Rank Movie Collection
[{
    "_id": ObjectId("59398daaad49f32c20115422"),
    "movie": ObjectId("5930ea4806fb9e365e0d55b5"),
    "count": 5
}, {
    "_id": ObjectId("59397f7095f0b91ffbdeb1f8"),
    "movie": ObjectId("583e3bd69e2ea90c69c5a254"),
    "count": 1
}, {
    "_id": ObjectId("59397f6695f0b91ffbdeb1f6"),
    "movie": ObjectId("5930eaa706fb9e365e0d55c8"),
    "count": 5
}]

If i am giving m_genres names as Crime,Thriller.The query should fetch top 10 items from rank movie which having m_genres names Crime,Thriller.How can i achieve this?
My JS Code
RankMovie
    .find(queryOptions)
    .limit(10)
    .skip(1 * 10)
    .populate('movie', 'm_tmdb_id  m_title m_generes ')
    .sort('-count')
    .exec(function(err, movies) {
        if(err){
            return res.status(404).json(err);
        }
        return res.status(200).json(movies);
    }).catch(function(error) {
        return res.status(500).json(error);
    });


ObectId values have been "obscured". Please fix them.

@NeilLunn :Question updated

Actually this "still" has the best method using .aggregate() with $lookup to join the data.
var wantedGenres = ["Action","Crime"];
var page = 1;

RankMovie.aggregate([
  { "$lookup": {
    "from": Movie.collection.name,
    "localField": "movie",
    "foreignField": "_id",
    "as": "movie"
  }},
  { "$unwind": "$movie" },
  { "$match": { "movie.m_genres.name": { "$in": wantedGenres }  }},
  { "$sort": { "count": -1 } },
  { "$project": {
    "movie": {
      "m_title": "$movie.m_title",
      "m_tmdb_id": "$movie.m_tmdb_id",
      "m_genres": "$movie.m_genres",
    },
    "count": 1
  }},
  { "$skip": 10*page },
  { "$limit": 10 },
])

This works out to be efficient since the $unwind and $match get combined into the $lookup itself, and only return the items that actually matched the given criteria in the $match as opposed to "ALL" related data. This is explained in the Answer to your previous question in full.
But this is what happens to those three stages:
    {
        "$lookup" : {
            "from" : "movies",
            "as" : "movie",
            "localField" : "movie",
            "foreignField" : "_id",
            "unwinding" : {
                "preserveNullAndEmptyArrays" : false
            },
            "matching" : {
                "m_genres.name" : {
                    "$in" : [ 
                        "Action", 
                        "Crime"
                    ]
                }
            }
        }
    }

Of course then we $sort in order to have the matching results in the correct and wanted order. Then it simply is a matter of selecting the wanted fields with $project ( note that $addFields will not work here, since we want to "overwrite" ) and performing the $skip and $limit for the pagination.
Trying to do this "client side" as .populate() does would be next to impossible and practically impossible in real situations. The problem of course being that the "selection by genres" needs to happen "before" you actually begin to "paginate".
So the only way that could possibly happen is with a "relatively small" list of "movies", because you would indeed need to make the selection on the "genres" first and then do the rest of the query.
The "totally impractical" way would look something like:
var wantedGenres = ["Action","Crime"];
var page = 1;

Movie.find({ "m_genres.name": { "$in": wantedGenres } })
  .select({ "_id": 1 })
  .exec()
  .then(movies =>
    RankMovie.find({ "movie": { "$in": movies.map(m => m._id) })
      .populate('movie', 'm_tmdb_id  m_title m_genres')
      .sort('-count')
      .skip(10*page)
      .limit(10)
      .exec()
  ).then(rankings => {
    // deal with response
  })
  .catch(err => res.status(500).json(err))

But of course that pulls "ALL" the matching "movies" over the wire to the client before issuing the query. And possibly breaks the BSON limit on request with the $in argument of ids.
The aggregate statement on the other hand, will not have the same limitation.

Thanks for you help.The first approach returning all the values from the movie document

@Muhsin You need the $addFields in there and it must be addressing the same name as what was used in the output from $lookup. This "overwrites" the full details with just the wanted fields. This is "by design". It is not presently possible to "restrict" the returned fields from a $lookup operation. So you need the stages exactly as presented here.

@Muhsin Actually I see it now. Unfortunately $addFields will not do. I was presuming the "nested" syntax would actually overwrite. It does not. Instead we need to $project and name all the fields. Let me correct.

Okay.Let me check
