我正在为日志管理系统设计我的第一个MongoDB数据库模式,我想将日志文件中的信息存储到mongoDB,我无法确定应该使用哪种模式 用于大型文档(嵌入式vs参考)。
注意:项目有很多来源,源有很多日志(在某些情况下有超过1 000 000个日志)
{
"_id" : ObjectId("5141e051e2f56cbb680b77f9"),
"name" : "projectName",
"source" : [{
"name" : "sourceName",
"log" : [{
"time" : ISODate("2012-07-20T13:15:37Z"),
"host" : "127.0.0.1",
"status" : 200.0,
"level" : "INFO",
"message" : "test"
}, {
"time" : ISODate("2012-07-20T13:15:37Z"),
"host" : "127.0.0.1",
"status" : 200.0,
"level" : "ERROR",
"message" : "test"
}]
}]
}
我的重点是从数据库读取数据(不写入)时的性能,例如过滤,搜索,分页等。用户可以按日期,状态等过滤源日志(因此我希望在用户搜索或过滤数据时专注于阅读性能)
我知道MongoDB有16Mbyte的文档大小限制,所以我担心如果我要为一个源提供1 000 000个日志这将如何工作(因为我可以为一个项目提供许多源,并且源可以有许多日志)。当我使用大型文档并希望获得良好的阅读性能时,我应该使用嵌入式或参考架构,有什么更好的解决方案?谢谢
答案 0 :(得分:3)
你的问题的答案都不是。您应该将模式展平为每个日志条目一个doc,而不是嵌入或使用引用,以便它可以扩展到16MB doc限制之外的任何内容,以便您可以访问MongoDB查询功能的全部功能和性能。
因此,请使用以下方法删除数组字段并将所有内容移至顶级字段:
{
"_id" : ObjectId("5141e051e2f56cbb680b77f9"),
"name" : "projectName",
"sourcename" : "sourceName",
"time" : ISODate("2012-07-20T13:15:37Z"),
"host" : "127.0.0.1",
"status" : 200.0,
"level" : "INFO",
"message" : "test"
}, {
"_id" : ObjectId("5141e051e2f56cbb680b77fa"),
"name" : "projectName",
"sourcename" : "sourceName",
"time" : ISODate("2012-07-20T13:15:37Z"),
"host" : "127.0.0.1",
"status" : 200.0,
"level" : "ERROR",
"message" : "test"
}
答案 1 :(得分:1)
我认为在数组中登录可能会变得混乱。如果项目和源实体没有任何属性(键),除了名称和日志不能存储很长时间,您可以使用{{3每个文档只有一个日志:
{_id: ObjectId("5141e051e2f56cbb680b77f9"),
p: "project_name",
s: "source_name",
"time" : ISODate("2012-07-20T13:15:37Z"),
"host" : "127.0.0.1",
"status" : 200.0,
"level" : "INFO",
"message" : "test"}
也请参考:capped collection
加盖的藏品保持自然秩序。因此,您不需要时间戳索引来按自然顺序返回日志。在您的情况下,您可能希望从特定源/项目中检索所有日志。您可以创建索引{p:1,s:1}
以加快此查询速度。
但我建议你做一些'基准测试'来检查性能。尝试上面的上限收集方法。并使用您建议的完全嵌入式架构尝试分段文档。此技术用于经典http://docs.mongodb.org/manual/use-cases/storing-log-data/问题。因此,只有在自定义大小超过的情况下,您才会在单个文档中存储每个源的这么多日志,并溢出到新文档。