如何查找属于该用户的所有文档?

时间:2014-05-09 05:14:45

标签: javascript mongodb mongoose

我有一组用户和帖子集合。

var PostSchema = new Schema({
  title: {type : String, default : '', trim : true},
  description: {type : String, default : '', trim : true},
  user: {type : Schema.ObjectId, ref : 'User'},
  slug: {type: String, trim: true, lowercase: true},
  createdAt  : {type : Date, default : Date.now}
})

如何找到属于特定用户的PostSchema的所有文档? 此外,是否可以通过user.username字段找到用户的所有帖子?

2 个答案:

答案 0 :(得分:0)

我就是这样做的,简单的(阅读:noob)方式:p。

按给定的userId获取帖子:

var PostSchema  =   new Schema({...});

//  allows you to call method findByUser() of the model of posts
//  with parameters: the user_id and the callback function (fn).
PostSchema.statics.findByUser    =   function(userId, fn) {
    this.find({user:userId}, fn);
};

//  we create the posts model.
posts       =   mongoose.model('posts', PostSchema),

//  example usage: find the posts from 'some_user_id' or '2a1a9a...'.
posts.findByUser(some_user_id || '2a1a9a8a3a2a1a9a8a32a1a3', function(err, docs) {
    //  ensure there are no errors and there were docs given.
    if (!err && docs) {
        //  will return the posts.
        console.log(docs);
    }
});

按用户名(模式用户)获取帖子 可以应用相同的方法,但我们首先在集合用户中搜索用户名的id。

//  the method we are going to make is dependent on the model/collection 'users',
var users       =   mongoose.model('users', UserSchema);

//  we create another static method on the schema of 'posts'.
PostSchema.statics.findByName = function(username, fn) {
    //  we search the user with username 'username'
    //  in model 'users'.
    //  Here, we also are assuming that username = unique.
    this.model('users').findOne({username:username}, function(err, doc) {
        //  ensure there are no errors and there were docs given.
        if (!err && doc) {
            //  we will use the statics we made above.
            //  i have a feeling i lose the context here, so i refer to this.model('posts'),
            //  maybe this.findByUser() als works; i could not test my code.
            this.model('posts').findByUser(doc._id, fn);
        }
        //  if there is a failure, quit and call fn.
        else fn(err, doc);
    });
};

这些是您的问题的“快速”解决方案。我认为它可以更有效/更好地完成。

对于您决定在用户​​中添加帖子或单独包含帖子,我的观点是:这是使您的代码面向未来的编码原则。 想想数据库何时变得庞大(= mongo的名称来自哪里),其中一个用户拥有超过1,000,000个帖子。 因此,每当您只想获取用户数据时,您还可以获得1,000,000个帖子文档。所以我认为最好将这些集合分开以防止这种情况发生。

old:getter从帖子中获取用户文档。

您可以为所有文档提供这样的方法:

PostSchema.methods.getUser = function(callback) {
    // be sure you have the mongoose object.
    mongoose.model('users').findById(this.user, callback);
};

所以你可以调用方法:

postDoc.getUser();

写在我的头顶,所以这是更多的伪代码。更多信息: http://mongoosejs.com/docs/guide.html

答案 1 :(得分:0)

给出一些基本设置:

var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var ObjectId = Schema.ObjectId;

mongoose.connect('mongodb://localhost/nodetest');

var userSchema = new Schema({
  name: { type: String, default: '', trim: true }
});

var postSchema = new Schema({
  title: { type: String, default: '', trim: true },
  description:  { type: String, default: '', trim: true },
  user: { type: Schema.ObjectId, ref: 'User' },
  slug: { type: String, trim: true, lowercase: true },
  createdAt: { type: Date, default: Date.now }
});

var User = mongoose.model( 'User', userSchema );

var Post = mongoose.model( 'Post', postSchema );

用户的一些数据:

{ "_id" : ObjectId("536c6bf6da1ee15a4c0d7dc6"), "name" : "Neil", "__v" : 0 }
{ "_id" : ObjectId("536c6e338534d6a6afd41f64"), "name" : "Bill" }

帖子:

{
    "_id" : ObjectId("536c6bf6da1ee15a4c0d7dc7"),
    "user" : ObjectId("536c6bf6da1ee15a4c0d7dc6"),
    "slug" : "this_post",
    "createdAt" : ISODate("2014-05-09T05:47:34.249Z"),
    "description" : "another post",
    "title" : "this post",
    "__v" : 0
}
{
    "_id" : ObjectId("536c6e878534d6a6afd41f65"),
    "user" : ObjectId("536c6e338534d6a6afd41f64"),
    "createdAt" : ISODate("2014-05-09T05:58:31.642Z"),
    "slug" : "this_here",
    "description" : "This here",
    "title" : "My Post"
}

通过Id查找用户是一个简单的查询:

Post.findOne({ user: "536c6bf6da1ee15a4c0d7dc6"  },function(err,doc) {
  console.log( doc );
});

通过" name"查找用户有点不同

Post.find({})
  .populate('user', null, { name: 'Neil' })
  .exec(function(err,posts) {
    posts = posts.filter(function(post) {
      return ( post.user != null );
    });

    console.log( posts );

  });

请注意这里使用filter。实际查询实际上会匹配Posts中的所有内容,populate的使用只是有条件的"填充"匹配的差距。我们更改了该查询只是为了返回您想要的名称。

但是这里的filter会减少结果。注意到这种情况正在发生"客户"并且不是"加入"以任何方式在服务器上。

所以有限制。如果要真正限制,请使用嵌入式文档。如果无法嵌入,您将需要以某种方式提供另一个参考,以便搜索"用户"找到他们的"帖子",然后检索帖子。

所有问题都在于你如何处理最适合你的问题。