我们在NodeJS中重写后端后,将我们的应用程序移到了MongoDB。我唯一能够思考的事情就是我应该如何处理user-to-user
消息的存储。我们的应用程序具有即时消息功能,使用相当多。
为了让您更好地了解,我们将采用以下方式查询数据。
.find(
{ message_to: new ObjectID("...") },
{ message_date: { $gte: timestamp } }
)
相当简单,获取自上次timestamp
以来timestamp
用户上次提取邮件的时间以来发送给用户的所有邮件。这样我们就只能请求新邮件。
我想弄清楚哪种方式可以更好地处理这类数据......
非规范化:
{
participant_one: ObjectID("..."),
participant_two: ObjectID("..."),
messages: [
{
message_from: ObjectID("..."),
message_to: ObjectID("..."),
message_type: "TEXT",
message_data: "Hello message",
message_date: new Date()
},
{
message_from: ObjectID("..."),
message_to: ObjectID("..."),
message_type: "TEXT",
message_data: "Hello message",
message_date: new Date()
}
]
}
或者我应该做这样的事情......
{
participant_one: ObjectID("..."),
participant_two: ObjectID("..."),
messages: [
ObjectID("..."),
ObjectID("..."),
ObjectID("..."),
ObjectID("..."),
ObjectID("..."),
]
}
messages
数组列出另一个收集此格式邮件的集合中的ObjectID:
{
message_from: ObjectID("..."),
message_to: ObjectID("..."),
message_type: "TEXT",
message_data: "Hello message",
message_date: new Date()
}
请注意,user-to-user
消息传递是我们应用程序中非常非常核心的功能,并且它经常被使用。目前,活跃用户之间的平均消息量为600 /会话。
答案 0 :(得分:0)
如果绝大多数查询都是通过message_to和message_date进行的,我建议收集消息的第三种结构:
{
participant_one: ObjectID("..."),
participant_two: ObjectID("..."),
message_from: ObjectID("..."),
message_to: ObjectID("..."),
message_type: "TEXT",
message_data: "Hello message",
message_date: new Date()
},
这实质上颠倒了你的关系,并使参与者从一个/两个从属于消息。优点是,使用此结构,您可以保持规范化,并且可以非常轻松地在所有消息属性上创建非常复杂的查询。
此外,使用mongo,很容易聚合结果,因此如果您需要与参与者关联的所有消息的数组(如上面的非规范化示例),则可以返回一个简单的查询或聚合(并且它将会如果在参与者字段上创建索引,也会很快。)
此外,从概念上讲,这种结构可以更好地模拟您的数据:消息是基本文档,所有其他字段都是属性(包括参与者等)。
如果您已经编写了一个应用程序(您提到您正在将预先存在的代码库转换为node.js),那么最好的办法是创建一个具有三种不同结构的测试数据库,然后运行应用程序的查询反对所有这三个,看看哪些用最简单的查询/代码给你最好的性能。