我是使用DocumentDB API的Azure Cosmos DB的新手。我计划对我的数据建模,以便一个文档引用另一个文档。这很简单,如Modeling document data中所述。但是,我还想将相关文档分成不同的集合(此决定与数据的partitioned如何相关)。
编辑7/24/2017 :回应一条评论,想知道为什么我选择使用单独的集合:单独集合的原因主要归结为分区键和读/写优先级。由于需要在集合中的所有文档中存在某个分区键,因此将所选分区键不属于的文档分开是有意义的。在对权重进行了大量权衡之后,我所确定的分区密钥是一种可以优化写入速度并在分片间均匀分布数据的分区密钥 - 但不幸的是,它在逻辑上并不属于我的“元数据”文档。由于元数据和测量之间存在一对一的关系,我选择在测量中使用对元数据的引用而不是嵌入。而且由于元数据很少(或永远不会)附加到每个测量中,我认为额外往返DB的费用是一个非常低的问题。
由于引用是未经数据库验证的“弱链接”,是否可以并且明智地存储其他信息,例如集合名称?也就是说,我们可以使用一种路径来代替只有一个字符串id?
Metadata document in collection "Metadata":
{
"id": "metadata1",
...
}
Measurement document in collection "Measurements":
{
"id": "measurement1",
"metadata-id" : "../Metadata/metadata1",
...
}
然后,当我解析我的应用程序/脚本中的数据时,我知道要查询的集合和文档。
最后,我假设有其他/更好的方法可以解决这个问题,我欢迎您的建议(例如下划线,而不是斜线;使用符号来表示集合,如$ Metadata;等等)。或者,我使用的关系跨越集合代码味道?
谢谢!
编辑:对于downvoter,您能否解释一下您的推理?我的问题不知情,不清楚或无用吗?为什么呢?
答案 0 :(得分:3)
你正在考虑这种错误的方式,并且因为你在每个收集级别收费而不需要“优化”会产生更多的成本。你应该做的是选择一个更通用的分区键。类似于key
或partitionKey
的内容。这里的权衡是你需要在你的客户端应用程序中确保你在所有文档上填充这个属性(它可能会导致重复的值,但最终还是可以的)。您可以继续使用您最初为测量文档选择的值,并为元数据文档设置不同的值。
我在这里的其他一些答案中已经广泛地写了这篇文章,我相信这是有效和大规模使用宇宙的最大误解之一。在许多Cosmos示例中,他们谈到选择像deviceId
或postal code
这样的partitionKey并不意味着你正在处理同类文档。
请参阅我就homogeneous vs heterogeneous in documentdb回答的这个问题。这种模式的最大争论是在Cosmos中新增了Graph API,这需要在单个集合中包含许多不同的types
实体,并且完全支持您描述的用例减去额外的集合。显然,在处理异构类型时,所有文档中都不会存在适合于分区键的单个属性,这就是您需要通用的原因。
答案 1 :(得分:1)
你要做的是可行的。您使用的约定并不是特别重要,只要您可以找出参考。但请记住,使用这种类型的“关系”会相当慢,因为您需要从一个集合中获取所有文档,然后在单独的查询中获取相关文档。它会对您的应用产生严重影响。
另一种可能性是优化您的数据以供阅读:您可以将元数据文档嵌入到其他文档中。您的数据将被复制,因此如果您更新这些文档,则必须在两个集合中更新它们,但您可能写的频率低于您阅读的频率(可能,如果不是这样,则此设置会更糟)。
您的文件如下所示:
Metadata document in collection "Metadata":
{
"id": "metadata1",
...
}
Measurement document in collection "Measurements":
{
"id": "measurement1",
"metadata" : {
"id": "metadata1",
...
},
...
}