2

我有一个包含许多消息的应用程序。每个用户都可以选择一条消息,以便将此消息发送给其他用户。最后这条消息会得到一个标志('消息被发送到: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 会更好地处理哪种情况?许多小文件还是不太大?哪种情况更适合执行分析,例如:显示来自一个发件人(用户名 1)的所有消息和收件人?

4

1 回答 1

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为您创建字段。

于 2013-08-15T14:49:44.307 回答