我有一个包含许多消息的应用程序。每个用户都可以选择一条消息,以便将此消息发送给其他用户。最后,此消息将获得一个标志('消息发送到:user1,user2,...)这些发送信息应存储在mongoDB中。 现在我正在考虑两种不同的方式:
1。)一个集合中的许多小文档
每个文档都包含消息ID,用户名,发送此消息的人员以及收件人数组,如下所示:
{
_id:'3DA5FC203,
sender:'username1',
recipient:['user1','user2','user3']
},
{
_id:'4AD290FC,
sender:'username1',
recipient:['user1','user2','user3']
},
{
_id:'4AD290FC,
sender:'usernameX',
recipient:['user2']
}
如果1000个用户每天向1个或更多收件人发送10封邮件,那么如果每年有360万个文档。
2。)一个集合中较小的文档
另一种方式是文件较少,但文件较大。例如,每条消息的一个文档,其中包含有关此消息的所有发件人和收件人的信息。 mongoDB条目可能如下所示:
{
_id:'3DA5FC203,
'username1':['user1','user2','user3'],
},
{
_id:'4AD290FC,
'username1':['user1','user2','user3'],
'usernameX'['user2']
},
在这种情况下:只有2个文件而不是3个(上面的例子),但是一个文件可能包含100个或更多的发件人。
所以我的问题:mongoDB会处理哪种情况更好?许多小文件还是不太大?哪种情况更适合执行分析,例如:显示所有邮件和来自一个发件人的收件人(username1)?
答案 0 :(得分:4)
使用键作为值,就像在:
中一样'username1':['user1','user2','user3'],
是一个坏主意,因为您无法在查找具有特定发件人的文档时进行索引查询。这有效:
db.messages.find( { 'username1' : { $exists: true } } );
但是不会很快。
保留第一个选项可能是明智的,每个邮件和发件人只有一个文档。 然后你可以这样做:
db.messages.find( { sender: 'username1' } );
可以使用以下方式将新收件人添加到此文档中:
db.messages.update(
{ 'msgid' : '867896', sender: "username1" },
{ 'recipient': { $push: "user4" } }
);
您可以通过以下方式使MongoDB对两个查询使用相同的索引:
db.messages.ensureIndex( { sender: 1, msgid: 1 } );
其他提示
您需要注意,您也不能拥有两个与第一个示例中具有相同_id
值的文档。因此,您必须确保将此ID添加为与_id
不同的字段。例如:
{
msgid:'3DA5FC203,
sender:'username1',
recipient:['user1','user2','user3']
},
让MongoDB为您创建_id
字段。