使用MongoDB进行内容标记

the*_*iki 7 tagging database-design mongodb

我想使用MongoDB实现内容标记.在关系数据库中,最好的方法是在内容(例如"产品")和标签表之间建立多对多关系.但是NoSQL数据库的最佳方法是什么?

会是更好地把每一个标签在标签的"内容"文件的阵列,或者投入到引用标签中的字符串?

Phi*_*ipp 11

在MongoDB中你有一个:m关系的大多数情况下,你应该使用嵌入而不是引用.所以我建议你在每个产品中都有一个带有标签名称的数组"标签".我认为查看单个产品将是您系统中最常见的用例.此设计允许您向用户显示带有单个数据库查询的标记名称列表的产品.

当您需要一些关于您不想绑定到产品的标签的其他元数据时(比如标签的长文本描述),您可以创建一个额外的标签集合,其中name字段获得唯一索引用于快速查找和避免重复.当用户单击或悬停在标记名称上时,您可以使用其他查询来获取标记详细信息.

此设计中存在问题的情况是您要删除或重命名标记时的情况.然后,您必须编辑包含标记的每个产品.但是因为MongoDB不像SQL数据库那样知道使用CASCADE ON DELETE的外键,所以当你有文件相互引用时,你总会遇到这个问题.

通过在产品的标记数组中存储objectID而不是名称,可以更轻松地重命名标记.但ID的缺点是它们对用户来说是无用的.您需要获取标签的名称以显示产品页面.这意味着您必须从tags集合请求每一个,这需要额外的数据库查询.

  • @MaxHodges无法对以逗号分隔的列表编制索引.当您想要查找具有特定标记的所有文档时,数据库别无选择,只能进行完整的集合扫描,并检查每个标记字符串是否出现子字符串.当集合很大时,此查询将花费很长时间.但另一方面,阵列可以被编入索引.数组上的索引将分别索引每个数组元素,因此通过索引查找具有特定标记的所有文档很快. (7认同)
  • 当然,您可以使用文本索引,但是1.每个集合只能有一个文本索引,因此您可能希望将其用于更合适的内容(如产品描述)和2.为实际文本设计文本索引而不是解析CSV.当然,当你的每个标签只有一个单词时它可以工作,但当你有带空格或连字符的标签时,它会破裂. (3认同)
  • 在这种情况下,我建议嵌入,我反对的建议是,嵌入"大多数情况"是正确的. (2认同)