假设我有两个集合:
Products
和Categories
。
后一个集合的文档有两个字段:
BSON ObjectId
)后者集合的文档有3个字段:
BSON ObjectId
)假设我有以下Product
文件:
{ "_id" : ObjectId("AAA"), "name" : "Shovel" }
假设我有以下Category
文档:
{ "_id" : ObjectId("BBB"), "Name" : "Gardening", "Products" : ["AAA"] }
出于本示例的目的,假设AAA
和BBB
是合法的ObjectId - 例如:ObjectId("523c7df5c30cc960b235ddee")
,它们等于内部ObjectId的字符串。
Products
字段应该存储为ObjectId(...)
而不是字符串吗?
答案 0 :(得分:1)
我认为这并不重要。
我很确定ObjectId格式对十六进制数进行编码,因此内存和带宽可能略高一些。我已经做到了两个方面。只要您决定,对于每个字段,您将如何对其进行编码,这两种方法都可以正常工作。
答案 1 :(得分:1)
只要您始终使用相同类型(以便正确进行比较),区别在于:
ObjectId
与同一String
值的ObjectId
表示进行比较。因此,ObjectId("523c7df5c30cc960b235ddee")
不等于"523c7df5c30cc960b235ddee"
。ObjectId
,当本地存储时,将存储为12个字节,加上字段名称ObjectId
作为字符串存储时,通常以24个字节存储(因为它将转换为十六进制数字),加上字段名称ObjectId
作为12个字节的大小优势确实无关紧要,因为字段名称远远超过字节大小时存储为字符串。我建议将它们存储为原生ObjectId
。某些驱动程序可以选择并透明地转换为ObjectId
到String
并返回,以便客户端代码可以更轻松地操作它。例如,C#驱动程序可以执行此操作,并且我已经使用它,以便在序列化为JSON时,ObjectId
采用易于在JavaScript中使用的简单格式。
答案 2 :(得分:0)
当您尝试从“类别”集合中查找产品的详细信息时,这将非常重要。
由于Mongo中没有服务器端JOIN,因此您的代码必须将文档匹配在一起。 ObjectIDs are encoded as 12 bytes,您可以轻松地用任何语言进行比较。使用字符串或对象id并不重要。
您面临的真正问题是数据规范化(或缺乏数据规范化)。如果您将Name
字段存储在Categories
文档中而不是ObjectID中,则可以在一次调用中返回产品名称(而不是多次调用,每类产品1次) )。
第一次这样做时感觉不对。毕竟,如果您更改了可能会或可能不会频繁出现的产品名称,则必须更新许多文档。您必须通过考虑应用程序使用它的方式来建模数据。
最后,索引Name
集合中的Prodcuts
属性。从Categories
文档中找到的字符串开始,获取产品的详细信息将非常快。
另一种方法是不要拥有Categories集合,而是在Category
文档中添加Products
属性。您可以找到具有{'Category':'Gardening'}
的文档。索引Category
字段可能是一个好主意。
同样,ObjectID或String并不重要。它是关于您的数据建模思考应用程序将如何使用它。