我正在为我的网站做一个通知系统。像facebook
这样的通知系统。或者stackoverflow
.我有2个问题。
-
如何存储在数据库中?我可以将所有通知存储在用户文档中吗?或者在单独的文档中(因为我认为 monogdb 在文档中的大小是有限的?或者,智能存储?(使用 Inc 或数据库中的值(请参阅:真/假),并具有复杂的查询)
-
如何为带到页面?例如,当我单击
inbox
中的链接以进行stackoverflow
时,我会重定向到该页面。但是我,我有一个multipage
的例子系统:我有100个朋友。每页列出 30 个。因此,当我单击通知时,我无法重定向到 ,因为不可能知道好的页面(可以删除用户)。
谢谢!如果你有其他想法,告诉我。谢谢。
编辑:
(对不起我的英语,我是法国人)
对于第一个问题,我意识到我必须等待时间来选择我的结构。因为我的通知是..有点复杂,所以提前到感觉。
第二,我解决了问题。我解释:(我以朋友为榜样,因为它很容易被取消。我像这样存储我的数据:
{
friends: [
{_id: xxxxx, ts: xxxx},
{_id: xxxxx, ts: xxxx}
]
}
想象一下,我显示所有朋友:每页 30 个。问题是:
- 当我想显示所有朋友时,我无法使用 MONGO 进行排序。(有点问题)
- 如果我想在一个特殊的朋友那里将用户引导到此列表(每页 30 个),请始终保持
sort
ts
.我无法知道页面。uniq的解决方案是获取所有文档。但是:性能非常糟糕。
所以,我像这样存储:
{
friends: {
xxxx: {ts:xxx},
xxxx: {ts:xxx}
}
}
知道我可以对文档进行排序,使用跳过和限制。因此,如果我想要一部分,我不需要带走所有文件。
要知道页面,我只需对 ts 进行<或>的数量,例如 11 个朋友与我想要的朋友的 ts>,并对所有朋友(例如:50 个朋友)进行计数,有 50 和 11,我可以猜到页面。或>
这个解决方案好吗?- 我需要计数- 查询>或<的数量我可以把列出朋友的页面,保持the sort ts
>
你可以不明白我为什么使用计数。我需要,因为它们不存储在同一个文档中。
2 编辑:
这个解决方案的问题在于我需要在mongo query
之外进行query object
和update object
(例如:用于 do friends.xxxxxx: {$exists:true}
ps:对于mongodb来说,使用ts
而不是date
有什么好处?我正在使用ts
但我想我会存储date
,没有ts
.
3 编辑
我会喜欢Sammaye
.存储在单独的文档中。看看:http://mongly.com/Multiple-Collections-Versus-Embedded-Documents/#1 和 http://openmymind.net/2012/1/30/MongoDB-Embedded-Documents-vs-Multiple-Collections/
@Stennie给出一个非常完整的答案。
然而,最近我在PHP中为我的网站做了类似的事情。首先要了解的是你是在做通知系统还是墙(两者有很大的不同),我似乎不清楚,我不确定你的意思:
如何为带到页面?例如,当我点击链接时 在我的收件箱中 堆栈溢出,我重定向到该页面。但是我,我 例如,有一个多页的系统:我有 100 个朋友。那里 每页列出 30 个。所以当我点击通知时,我不能 重定向至 因为不可能知道好的页面(用户 可以删除)。
这不是很好的英语,当我阅读它时非常混乱。如果你能扩展一下,我相信人们可以回答得更好。
对于通知系统,我发现大量通知对象也可以工作。所以我有一个这样的架构:
{
_id: {},
to_user: ObjectId{},
user_id: ObjectId{}, // Originating user
custom_text: "has posted a new comment on your wall post",
read: false,
ts: MongoDate()
}
从字面上看,这将是我必须生成通知的文档。每次用户提交生成通知的操作时,它都会向数据库写入一个新行,每次都会填充to_user
,每个用户都需要收到通知。至于多个用户提交相同的操作,我实际上转换了OjbectId
列表中的user_id
字段,所以我可以说:
Sam, Dan and Mike all commented on your wall post
然后,我通过ts
存储用户在其行中查看的最后一个ts
来进行查询,从而允许我每次对最新通知执行基于范围的查询。根据我的个人经验,这对于分片和查询非常有效。
希望对您有所帮助,
是嵌入还是链接是MongoDB中数据建模的常见问题。 如果您的通知数量是无限的,您可能会更好地将它们保存在单独的集合中。
当前的 16Mb 文档限制实际上并不像其他一些考虑因素那样是一个问题:
-
将所有通知包含在单个文档中可能会遇到的性能问题是,快速增长的文档可能还需要更频繁地在数据库中重新定位(请参阅填充因素)。
-
您可能希望在很短的时间内对文档应用多个更新(例如在通知上设置"读取"标志),这意味着更新同一文档的争用更多(请参阅原子操作)。
为了实现分页,您可以将 limit() 与范围查询或 skip() 结合使用。 范围查询(例如,基于索引notificationDate
)将更有效地使用索引,并且随着集合的增长,性能优于skip()
。