我有一组用户和帖子集合。
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字段找到用户的所有帖子?
答案 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个帖子文档。所以我认为最好将这些集合分开以防止这种情况发生。
您可以为所有文档提供这样的方法:
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
会减少结果。注意到这种情况正在发生"客户"并且不是"加入"以任何方式在服务器上。
所以有限制。如果要真正限制,请使用嵌入式文档。如果无法嵌入,您将需要以某种方式提供另一个参考,以便搜索"用户"找到他们的"帖子",然后检索帖子。
所有问题都在于你如何处理最适合你的问题。