【问题标题】:MongoDB Mongoose schema designMongoDB Mongoose 模式设计
【发布时间】:2015-06-27 23:05:09
【问题描述】:

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

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

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

此外,用户可以关注其他用户。帖子可以被其他用户点赞。 我想查询User的followers和User的following,有限制、跳过、排序等猫鼬功能。我也想查询用户喜欢的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) { ... });

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

【问题讨论】:

    标签: node.js mongodb mongoose


    【解决方案1】:

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

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

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

    编辑:添加跳过/限制选项以显示分页示例

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

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

    【讨论】:

    • 是的,我可以使用填充。但是,想象一下如果我有很多用户。然后,如果我填充它,并将它们发送到前端,那将是很多数据。我正在考虑如何实现分页/无限滚动。
    • 您应该在原始问题中如此说明。如果您不指定您的需求,您就不能指望满足您需求的解决方案。也就是说,没有理由不能使用上面的答案作为起点来实现分页/无限滚动解决方案。但是,如何实施这样的解决方案超出了您的问题范围。
    • 好的,抱歉。如何使用您的解决方案实现分页?因为在标准查询中,我只能做限制和跳过,但是使用填充,没有这样的选项。
    • .populate() 具有可用于实现分页的 skiplimit 选项。我会更新我的答案。
    • 哦,太好了!这正是我所需要的。
    猜你喜欢
    • 2015-01-09
    • 2019-06-12
    • 1970-01-01
    • 2018-10-18
    • 2015-01-26
    • 2016-03-29
    • 1970-01-01
    • 2014-02-04
    • 2011-11-25
    相关资源
    最近更新 更多