我想创建一个活动模型,以便在我的应用程序中显示时间轴类型,但我不知道如何动态引用mongoose模式中的集合。我正在使用猫鼬(3.6.20)
到目前为止,演员总是一个用户,但_object可以是用户或帖子。
这就是我所拥有的:
userSchema = new Schema({
_id: ObjectId;
name: String
});
postSchema = new Schema({
_id: ObjectId;
author_id: String, ref: User
});
我想做的是:
activitySchema = new Schema({
_object: { String: Id of the thing, ref:'can be user or post'} // Object that the verb occurred on... can be a post or a user
actor: { type: String, ref: 'User' },
action: { type: String, default: ""}, //ex: has replied to:, or started following:
});
如果可能的话,如何使用带有mongoose的动态引用来解决这个问题,我将如何填充它?
谢谢!
答案 0 :(得分:16)
2017年更新..
现在可以使用refPath或甚至多个动态引用来动态引用。
var userSchema = new Schema({
name: String,
connections: [{
kind: String,
item: { type: ObjectId, refPath: 'connections.kind' }
}]
});
上面的refPath属性意味着mongoose将查看connections.kind路径以确定用于populate()的模型。换句话说,refPath属性使您可以使ref属性动态化。
答案 1 :(得分:10)
如果您希望不存在可能存储在_object
中的每种模型类型的多个属性,那么这是一种如何定义模式的模式:
var UserSchema = new Schema({
name: String
});
var PostSchema = new Schema({
author: { type: Schema.Types.ObjectId, ref: 'User' }
});
var ActivitySchema = new Schema({
_object : Schema.Types.ObjectId,
actor: { type: Schema.Types.ObjectId, ref: 'User' },
action: { type: String, default: "" }
});
var models = {
User : mongoose.model('User', UserSchema),
Post : mongoose.model('Post', PostSchema),
Activity : mongoose.model('Activity', ActivitySchema)
};
UserSchema
。您不需要定义_id
字段,因为它是ObjectId
为您自动创建的。PostSchema
定义User
并引用ref
个实例。 type
是ObjectId
(默认情况下定义模型
_ id`s的方式)。ActivitySchema
。在这种情况下,请勿定义ref
类型,因为它未知。只需存储核心ObjectId
类型。当您想要创建Activity
个实例时,它没有太大区别:
var activity = new models.Activity( {
_object: post._id,
actor: user._id,
action: "post"
});
无论如何,您总是使用model._id
语法。
此外,如果您知道对象的类型,则可以使用populate
。例如,post
行动可能意味着_object
包含User
:
models.Activity.find({action: 'post'}).populate({
path: '_object'
, select: 'name'
, model: 'User'
}).exec(function (err, activities) {
console.log(activities);
})
答案 2 :(得分:5)
为什么acitivitySchema没有两者兼而有之?
activitySchema = new Schema({
user:{ type:ObjectId, ref:'User' },
post:{ type:ObjectId, ref:'Post' },
actor: { type: String, ref: 'User' },
action: { type: String, default: ""}, //ex: has replied to:, or started following:
});
当您获得猫鼬对象时,只需调用populate('user')并填充('post')。它将根据保存的内容填充用户或帖子。 Mongodb非常有效率。
答案 3 :(得分:2)
如果你想让mongoose populate
工作,而且架构变量数量有限,你需要做一个“稀疏模型”:
activitySchema = new Schema({
user: {type: ObjectId, ref: 'User'},
post: {type: ObjectId, ref: 'Post'}
actor: { type: String, ref: 'User' },
action: { type: String, default: ""}, //ex: has replied to:, or started following:
});
这样可以正常工作,您只需编写代码即可了解其中一个将为null。由于其他风格与查询不匹配,因此查询这些风格也非常容易。
但是,否则,您不能使用mongoose populate
,但是,在您的活动架构中粘贴modelId
和modelName
,然后加载相应的模型文档大约为3行代码,所以如果你真的喜欢使用可以引用不同集合的单个字段,那么不要冒汗写点什么。