Christian Sakai
Christian Sakai

Reputation: 979

MongoDB Mongoose schema design

I have a schema design question. I have a UserSchema and a PostSchema.

var User = new Schema({
  name: String
});

var Post = new Schema({
 user: { type: Schema.Types.ObjectId } 
});

Also, user is able to follow other users. Post can be liked by other users. I would like to query User's followers and User's following, with mongoose features such as limit, skip, sort, etc. I also want to query Post that a user likes.

Basically, my only attempt of solving this is to keep double reference in each schema. The schemas become

var User = new Schema({
  name: String,
  followers: [{ type: Schema.Types.ObjectId, ref: "User" }],
  following: [{ type: Schema.Types.ObjectId, ref: "User" }]
});

var Post = new Schema({
 creator: { type: Schema.Types.ObjectId, ref: "User" },
 userLikes: [{ type: Schema.Types.ObjectId, ref: "User" }]
});

so, the code that will be used to query

// Find posts that I create
Post.find({creator: myId}, function(err, post) { ... });

// Find posts that I like
Post.find({userLikes: myId}, function(err, post) { ... });

// Find users that I follow
User.find({followers: myId}, function(err, user) { ... });

// Find users that follow me
User.find({following: myId}, function(err, user) { ... });

Is there a way other than doing double reference like this that seems error prone?

Upvotes: 4

Views: 942

Answers (1)

JME
JME

Reputation: 3642

Actally, you don't need the double reference. Let's assume you keep the following reference.

var User = new Schema({
  name: String,
  following: [{ type: Schema.Types.ObjectId, ref: "User" }]
});

You can use .populate() to get the users you're following:

EDIT: added skip/limit options to show example for pagination

User.findById(myId).populate({ path:'following', options: { skip: 20, limit: 10 } }).exec(function(err, user) {
  if (err) {
    // handle err
  }
  if (user) {
     // user.following[] <-- contains a populated array of users you're following
  }
});

And, as you've already mentioned ...

User.find({following: myId}).exec(function(err, users) { ... });

... retrieves the users that are following you.

Upvotes: 4

Related Questions