MongoDB 猫鼬模式设计

MongoDB Mongoose schema design

我有一个架构设计问题。我有一个 UserSchema 和一个 PostSchema。

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

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

此外,用户还可以关注其他用户。 Post 可以被其他用户点赞。 我想查询User的followers和User's following,有mongoose的功能,比如limit, skip, sort等。我还想查询一个用户喜欢的Post

基本上,我解决这个问题的唯一尝试是在每个模式中保留双重引用。架构变为

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" }]
});

所以,将用于查询的代码

// 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) { ... });

除了像这样进行双重引用之外,还有其他容易出错的方法吗?

实际上,您不需要双重引用。假设您保留 following 参考。

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

您可以使用 .populate() 获取您关注的用户:

编辑:添加了 skip/limit 选项以显示分页示例

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
  }
});

而且,正如您已经提到的...

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

...检索关注您的用户。