Farhan Tahir
Farhan Tahir

Reputation: 2134

Paginated results in mongoose with filters on reference document

I have a user and post document as follow:

user: {
"name": "Test",
interests: [
  "Sports",
  "Movies",
  "Running"
 ]
}

post: {
 "title": "testing",
 "author": ObjectId(32432141234321411) // random hash   
}

I want to query posts and fetch all those posts with author have "sports", "Running" as interests and this will be a paginated query.

How can I do so in mongoose and if not what alternative shall I use ?

Upvotes: 1

Views: 1669

Answers (2)

Farhan Tahir
Farhan Tahir

Reputation: 2134

I used following approach though giving answer with async/await approach but I actually used it using promises.

const fetchPosts = async (req, res) => {
  //First find users having those interests.
 const users = await User.find({ 
    interests: {
     "$in": ["Sports", "Movies"]
    } 
  })
  .select('_id')
  .exec();

 // map over array of objects to get array of ids
 const userIds = users.map(u => u._id);

 // Then run an in filter on Post collection against author and 
 //userIds
 const posts = await Post.find({
   author: {
     "$in": [userIds]        
    } 
  }) 
  .limit(15)
  .skip(0)
  .exec();
}

Upvotes: 0

Rahul Sharma
Rahul Sharma

Reputation: 10071

Pagination using limit and skip

var limit = 5;
var page = 0; // 1,2,3,4

return Model.find({
        /* Some query */
    })
    .limit(limit)
    .skip(limit * page)
    .exec().then((data) => {
        console.log(data);
    });

Try this

const findUser = (interests) => {
    return User.find({
        interests: {
            $in: interests
        }
    }).exec();
};

const findPost = (query, page = 0) => {
    const limit = 5;
    return Model.find(query)
        .limit(limit)
        .skip(limit * page)
        .exec();
};

var execute = async () => {
    const users = await findUser(["Sports", "Movies", ]);
    users.forEach(user => {
        user.post = await findPost({
            "post.author": user._id
        });
    });
    return users;
}

Upvotes: 1

Related Questions