具有动态参考的Mongoose Activity模型

mau*_*ado 3 mongoose mongodb node.js

我想创建一个活动模型,以便在我的应用程序中显示时间轴类型,但我不知道如何动态引用mongoose模式中的集合.我用猫鼬(3.6.20)

在我到目前为止,演员总是一个用户,但_object可以是用户或帖子.

这就是我所拥有的:

userSchema = new Schema({
    _id: ObjectId;
    name: String
});

postSchema = new Schema({
    _id: ObjectId;
    author_id: String, ref: User
});
Run Code Online (Sandbox Code Playgroud)

我想做的是:

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:
});
Run Code Online (Sandbox Code Playgroud)

如果可能的话,如何使用带有mongoose的动态引用来解决这个问题,我将如何填充它?

谢谢!

kei*_*ics 19

2017年更新..

你现在可以使用refPath或甚至多个动态引用来动态引用.

    var userSchema = new Schema({
    name: String,
    connections: [{
        kind: String,
        item: { type: ObjectId, refPath: 'connections.kind' }
        }]
    }); 
Run Code Online (Sandbox Code Playgroud)

上面的refPath属性意味着mongoose将查看connections.kind路径以确定用于populate()的模型.换句话说,refPath属性使您可以使ref属性动态化.

http://mongoosejs.com/docs/populate.html 动态参考

  • 这应该就是答案! (4认同)
  • 救星,上帝保佑你 (2认同)

Wir*_*rie 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)
};
Run Code Online (Sandbox Code Playgroud)
  1. 创建UserSchema.您不需要定义_id字段,因为它是为您自动创建的ObjectId.
  2. 使用定义PostSchema和引用User实例ref.的type是一个ObjectId(这是模型的方式_id`s are defined by default).
  3. Define the ActivitySchema.在这种情况下,请不要定义ref未知的类型.只需存储核心ObjectId类型.

当你想创建一个Activity实例时,它并没有太大的不同:

var activity = new models.Activity( {
   _object: post._id,
   actor: user._id,
   action: "post"
});
Run Code Online (Sandbox Code Playgroud)

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);
})
Run Code Online (Sandbox Code Playgroud)


Pra*_*evu 6

为什么不是acitivitySchema兼得?

activitySchema = new Schema({
    user:{ type: Schema.Types.ObjectId, ref:'User' }, 
    post:{ type: Schema.Types.ObjectId, ref:'Post' }, 
    actor: { type: String, ref: 'User' },
    action: { type: String, default: ""}, //ex: has replied to:, or started following:
});
Run Code Online (Sandbox Code Playgroud)

当你得到猫鼬对象时,只需调用populate('user')并填充('post').它将根据保存的内容填充用户或帖子.Mongodb在这方面非常有效.