Mongoose/MongoDB用户通知方案建议

dri*_*hev 16 mongoose mongodb

我想知道用户/通知类型的最佳方案是什么,如下所示:

  • 您有多个用户.
  • 您有多个通知可能针对单个用户,某些用户或所有用户.
  • 您需要在存储中提供通知"读取"条目,以了解用户是否已阅读通知.

方案一

嵌入式通知方案

Notifications = new Schema ( {
    message : String,
    date : { type : Date, default: Date.now() }
    read : { type: Boolean, default : false }
});

User = new Schema( {
    username : String,
    name : String,
    notifications : [Notifications]
});
Run Code Online (Sandbox Code Playgroud)

优点:

  • 显示数据非常容易,因为调用User.find()会将通知显示为数组对象.

缺点:

  • 为每个用户创建通知时,需要对每个嵌入的通知执行.push
  • 每个用户的多个通知条目(数据库中的多个数据)
  • 巨型嵌入式文件(我读了一些关于<4MB限制的东西)
  • 由于它是嵌入式文档 - (mongoose DocumentArray),您无法搜索或跳过.每次访问用户时都会加载每个通知.

方案二

填充(DBRef like)对象

Notification = new Schema ({
    message : String,
    date : { type : Date, default : Date.now() }
});

UserNotification = new Schema ({
    user : { type : Schema.ObjectId, ref : 'User' },
    notification : { type : Schema.ObjectId, ref : 'Notification' },
    read : { type : Boolean, default : false }
});

User = new Schema( {
    username : String,
    name : String,
    notifications : [ { type : Schema.ObjectID, ref : 'UserNotification' } ]
});
Run Code Online (Sandbox Code Playgroud)

优点:

  • 最适合查询
  • 没有重复的数据
  • 支持大量通知

缺点:

  • 你有3个集合,而不是一个(选项一只有一个集合)
  • 每次访问集合时,您都有3个查询.

问题

  1. 您认为这两个方案中最好的方案是什么?
  2. 我错过了某些基本的NoSQL知识吗?
  3. 有人能提出更好的方案吗?

提前谢谢你,我很抱歉这篇长篇文章,但我想我无法解释它更简单.

mpo*_*ien 12

选项1看起来可能会导致大量过多的文档增长和移动,这对性能有害,因为大多数写入都将转到嵌入式文档(通知).

选项2我对你的策略并不完全清楚 - 如果你已经在通知表中通过ID引用用户,那么拥有这3个集合似乎是多余的,但是也可以通过objectId嵌入一个通知列表.您可以在Notifications表中为用户编制索引,然后删除Users表中的嵌套数组.

(编辑)这是另一个需要考虑的策略.

三个看起来像这样的集合:

Users:
   _id: objectid
   username : string
   name: string

Notifications:
   _id:  objectid
   to (indexed):   objectid referencing _id in "users" collection
   read: boolean

Global Notifications:
   _id: objectid
   read_by: [objectid referencing _id in users]
Run Code Online (Sandbox Code Playgroud)

对于针对单个用户的通知,请插入该用户的通知.对于多个用户,为每个用户插入一个(或者,您可以将"to"字段设为数组并存储所有收件人的_ids,然后维护已读取所有收件人的所有收件人的另一个列表).要向所有用户发送通知,请插入Global Notifications集合.当用户读取它时,将其用户的_id添加到read_by字段.因此,要获取用户的所有未读通知的列表,您需要执行两个查询:一个用于通知,一个用于全局通知.

  • 是否有可能对你最后做了什么做出反馈?你会推荐什么? (3认同)