我有一个用户文档,其中包含与页面上的组件有关的多层嵌套对象。
"featuredImage": {
"config": {
"style": {
"margin": {
"right": 0,
"left": 0,
"top": 0,
"bottom": 30
},
"background": "rgba(0, 0, 0, 0)"
},
"class": "ss-article-featured-image"
}
},
"info": {
"date": {
"config": {
"style": {
"margin": {
"right": 5,
"left": 5,
"top": 0,
"bottom": 0
},
"fontWeight": "normal",
"fontSize": 16,
"background": "rgba(0, 0, 0, 0)",
"color": "inherit"
},
"show": true,
"class": "ss-article-date"
}
},
...
...
此用户文档上可能有〜50个组件(嵌套对象)(平均文档大小为10kb)。
我正在使用Mongoose的“默认值”来自动填充内容(例如0,或者未明确提供的字符串)。
当我查询该用户时,查询速度很快,我可以通过ID查找它,但是即使对本地数据库本地主机来说,对文档结果的计时最终也要> 10ms。 当我在Heroku上(从连接的数据库中)执行此操作时,大约需要30ms-100ms。
当我使用lean()
时,查询要快得多:〜5ms
(仅供参考,我只是将查询调用包装在console.time
中以对其计时)
.lean()会清除默认值,而我依赖默认值来渲染内容,因此这并不是一个选择。
关于此文档样式,是否会导致猫鼬的此类开销?是默认值吗?是否存在这么多嵌套对象的事实?该文档本身并不大,我的用户的平均文档大小为10kb。
{p1}查找50毫秒非常糟糕。但这似乎是导致问题的文档的“大小”或“样式”。同样,该文档也不大。
有人可以在这里亮点吗?
答案 0 :(得分:0)
对于大型对象(例如,您的(10K))和使用默认对象,没有什么要考虑的。在这种情况下,Mongoose非常繁琐,因为它必须为您提供从模式中定义的Mongoose模型,该模型是在从MongoDB检索结果后使用默认值等处理的。
这就是为什么您看到并使用lean()
的原因,因为它removes that overhead and returns just plain objects with no mongoose sugar around them。由于您依赖默认值,因此这也会使您付出代价。
建议不要返回完整的对象,而只返回所需的字段。我认为您几乎不需要整个10K文档。
Docs on how to select and return partial (specific fields only) result
有关如何更新basically just using $set局部模型的文档
另一种建议是,尽管有些激进的做法是考虑让像您这样的情况降级到mongoDB本机驱动程序并使用它,因为与Mongoose相比,在像您这样的大型对象上这样做要快得多。