Reputation: 23
Technology: MongoDB, ExpressJS
I have 3 schema
userSchema = {
name: {type: String},
password: {type: String},
email: {type: String},
friends: {type: [mongoose.Types.ObjectId]}
}
textPostSchema = {
text: {type: String},
postType: {type: String, default: "textPost"},
userId: {type: mongoose.Types.ObjectId}
}
articalPostSchema = {
title: {type: String},
content: {type: String}
postType: {type: String, default: "articalPost"},
userId: {type: mongoose.Types.ObjectId}
}
now I have one social media application in which I have to show these two post when user's friend post's a post, and include infinite scroll. Both textPost
and articalPost
should be send if to frontend and only total 10 post should be sent at a time. How should I write a API for timeline?
output should look like:
{
post: [
{
title: "artical Post title",
content: "artical post content",
postType: "articalPost",
userId: "60b9c9801a2a2547de643ccd"
},
{
text: "text post ",
postType: "textPost",
userId: "60b9c9801a2a2547de643ccd"
},
... 8 more
]
}
UPDATE: I got the solution:- I created on more schema:
timelineSchema = {
postId: {
type: mongoose.Types.ObjectId,
required: true,
ref: function () {
switch (this.postCategoryType) {
case 'articleposts':
return 'ArticlePost';
case 'textposts':
return 'TextPost';
}
},
},
postCategoryType: {
type: String,
required: true,
},
userId: {
type: mongoose.Types.ObjectId,
required: true,
ref: 'User',
},
},
and then I created one function to get only friends post:
exports.getTimelinePosts = async (req, res) => {
try {
const timelinePosts = await TimelineModel.find({
userId: { $in: [...req.user.friends, req.params.id] },
})
.skip((req.params.page - 1) * 10)
.limit(10)
.sort({ createdAt: -1 })
.populate('postId');
return res.status(200).json({ status: 'success', data: timelinePosts });
} catch (error) {
return res.status(500).json(error);
}
};
Upvotes: 2
Views: 508
Reputation: 1104
To implement the pagination with Mongoose, You can do something like that.
const getPosts = async (userId, pageNumber) => {
let result = await Post.find({ userId })
.skip((pageNumber - 1) * 10)
.limit(10);
return result;
};
pageNumber
is a counter that you need to pass from the frontend and will be incremented by 1 whenever a user hits the scroll limit.
If you want to query and merge data from multiple collections you need to update your schema to use populate
. Just include ref
where you are referring to other collections.
This may help. https://mongoosejs.com/docs/populate.html
Upvotes: 1
Reputation: 455
Assuming you are using express and mongoose. The code to fetch both,
// first bring all those schema from your mongoose models
const Article = require('./models/ArticleSchema');
const Text = require('./models/TextSchema');
const fetchArticleAndTextPost = async (req, res)=>{
//find all data
const articles = await Article.find();
const texts = await Text.find();
//join them together
const post = articles.concat(texts);
return res.status(200).json({
status: 200,
data: post,
})
}
Upvotes: 1