如何在MongoDB中标记文档?
我需要标记集合中的文档,我们称之为“联系人” 我的第一个想法是为每个文档创建一个名为“tags”的属性。 那么,在这种情况下,我们有一些类似:如何在MongoDB中标记文档?,mongodb,collections,tags,lookup,Mongodb,Collections,Tags,Lookup,我需要标记集合中的文档,我们称之为“联系人” 我的第一个想法是为每个文档创建一个名为“tags”的属性。 那么,在这种情况下,我们有一些类似: { _id:'1', contact_name:'Asya Kamsky', tags:['mongodb', 'maths', 'travels'] } 现在,让我们假设有用户想要在“联系人”中标记任何文档 如果我们决定保存每个文档的tags属性,因为标记是个人的,我们需要为每个标记使用userId。 所以我们的文档应该是这样的(或者不是): 现在,
{
_id:'1',
contact_name:'Asya Kamsky',
tags:['mongodb', 'maths', 'travels']
}
现在,让我们假设有用户想要在“联系人”中标记任何文档
如果我们决定保存每个文档的tags属性,因为标记是个人的,我们需要为每个标记使用userId。
所以我们的文档应该是这样的(或者不是):
现在,让我们把它复杂化一点。假设我们有很多用户,每个人都想用自己的个人标签来标记文档
如何处理
好的,我们可以为每个文档创建数千个标记:
{
_id:'1',
contact_name:'Asya Kamsky',
tags:[
{userId:'alex',tags:['mongodb', 'maths', 'travels']},
{userId:'eric',tags:['databases', 'friends', 'japan']},
{.....................................................}
{.....................................................}
{......................................................}
]
}
但是,如果我们有数百万用户呢?在这种情况下,我知道每个文档都有16mg的限制
在这一点上,担心我的应用程序的未来增长,我决定
要创建一个称为“标记”的独立集合,该集合将包含类似以下内容的文档:
{
"contact_name" : "Asya Kamsky",
"useriId" : "alex",
"tags" : ['mongodb', 'maths', 'travels'],
"timestamp" : "2017-08-08 14:33:28"
},
{
"contact_name" : "Asya Kamsky",
"useriId" : "eric",
"tags" : ['databases', 'friends', 'japan'],
"timestamp" : "2017-08-08 14:33:28"
}
也就是说,我们有一个单独的文档,表示每个用户的标签
又酷又干净,对吧
在这种情况下,我们面临两个问题:
谢谢大家如果您的使用使得每个联系人的
用户数量
X标签数量/大小
(加上联系人
文档中的任何其他数据)可能使您接近16MB文档大小限制,那么将标签存储在单独的集合中似乎是有效的。但在你走这条路之前,你确定这是可能的吗?您是否尝试过创建联系人文档以查看有多少标签,每个联系人有多少用户将使您接近16MB的限制。如果答案意味着许多用户和/或标签,你可能不太可能达到,那么你的担心是严格的理论,你可以考虑使用最简单的解决方案,即嵌入用户特定的标签在代码>联系人< /代码>。
此答案的其余部分假设大小估计值以及您对每个联系人的标签和用户可能数量的了解是有效的。在此基础上,您阐述了对连接性能的具体关注
但由于我想确保未来的良好表现,我想有10000000个联系人。所以,正如我最近研究的那样,$lookup在宇宙的“一小部分”中运行得很好,即使使用索引,这个搜索也会花费很多时间来执行
你试过衡量这个表现吗?为联系人
和标记
生成种子文档,然后保存这些文档的变体,然后使用$lookup运行查询并测量性能。您可以对一些基准测试执行此操作,例如:
- 1000个联系人和10000个标签
- 100000个联系人和1000000个标签
- 1000000个联系人和10000000个标签
- 10000000个联系人和100000000个标签
explain()
了解MongoDB内部的情况
您可能会发现性能是可以接受的,只有您知道这一点,因为您了解系统用户对性能的期望
最后一点,如果这里的用例是给定用户想要找到他们所有的联系人和标签,那么这可以通过“客户端连接”来处理,即两个查询(1)来获取“userId”的标签“…”
,(2)来查找这些标签引用的联系人。根据您的用例,这可能比服务器端连接(aka$lookup)更有效
{
"contact_name" : "Asya Kamsky",
"useriId" : "alex",
"tags" : ['mongodb', 'maths', 'travels'],
"timestamp" : "2017-08-08 14:33:28"
},
{
"contact_name" : "Asya Kamsky",
"useriId" : "eric",
"tags" : ['databases', 'friends', 'japan'],
"timestamp" : "2017-08-08 14:33:28"
}