10

是否可以在 documentDB 中使用身份列进行自动增量,它通常对 ID 很方便?任何与之相关的链接或提示都会很有用。

谢谢。

4

2 回答 2

9

AFAIK,DocumentDB 没有这种概念。DocumentDB 中的每个文档都有一个id唯一标识文档的属性,但该id字段是字符串类型。创建文档时,您可以选择不为此字段指定值,DocumentDB 会自动分配一个 id,但该值是一个 GUID。因此,如果您希望实现自动增量类型的功能,则需要自己处理。但是请记住,它是一个字符串类型的属性,所以即使您自己处理它,您也需要用零填充您的字符串,以便以正确的顺序返回值,即 1、2、3 等。而不是 1, 10, 11, ... 19, 2, 20 ....

于 2014-11-02T16:54:28.373 回答
7

仍然(截至 2016 年 8 月)没有内置Identity功能;DocumentDB 的反馈论坛上有这样的请求,可以在 这里投票。但请记住,自动计数器在某种程度上违背了大多数 NoSQL 设计理念。

但是,有几种方法可以作为解决方法,并且都有一个警告;第一种方法是Counter Document在存储过程中使用更新:

存储程序和反文件

  1. 创建一个包含数值属性的文档。要么缓存它的自链接,要么最好用一个已知的 id 创建它,比如“__ DocumentType _Counter”,然后你可以使用 UriFactory 来构建一个文档链接,这样就可以有效地“直接”访问 this Counter Document

  2. 创建一个接受要插入的 Document 的存储过程,以及Counter Document. 在此存储过程中,选择 Counter 的值,将其递增,将其分配给要插入的 Document 的相关属性,如果成功持久化,则将递增的值保存为 Counter Document 的更新。

这种方法将起作用,因为存储过程作为事务自动执行。

警告Counter Document:但是,事务目前仅在集合的边界范围内 -当将文档插入另一个集合时,您不能在一个集合中使用此方法。

雷迪斯

探索的第二个选项是创建一个 Azure Redis,它增加了一点复杂性和一点额外成本,并且在文档的增量和插入方面不是完全事务性的(但以我的个人经验提供更大的吞吐量)缓存,并将 Counter 值保存在 Redis 键值存储中,然后使用 LUA 脚本对其进行查询和递增。

这确保了对 Counter 值及其增量的查询是原子事务,因为 Redis 是单线程的,并且 LUA 脚本基本上会阻塞直到完成(但执行速度非常快)。

也可以使用 MULTI - EXEC 命令。这些都有自己的问题,需要调查以查看它们是否与您相关。

有关 Redis 事务的更多信息,请参见此处 - Redis 中的事务

警告:如果持久化您的文档失败,则您有“幽灵”ID,您可能接受也可能不接受。

更新:为了回应关于“在每个创建操作中增加 RU 成本”和“序列化所有写入”的评论 -是的,显然,在使用该Counter Document方法时,创建需要递增Identity属性的文档时就是这种情况;其他插件不会受到影响

在使用 DocumentDB 时,这两种“成本”都是满足所需功能所必需的——这本身并不支持Identity属性的概念;持久性到文档以确保恢复/连续性,序列化以保持一致性。RU 成本通常可以忽略不计,可以使用批处理等技术来抵消这一点。

当前没有不持久化计数器或序列化写入的 DocumentDB 替代方案,同时保证来自多个调用者的递增计数器的完整性。

DocumentDB 团队的 Andrew Liu 的建议确实是使用 aCounter Document,如链接问题中所述- 另请注意 Andrew 答案下方的评论。

由于存储过程是在 DocumentDB 中预编译的,因此它们是执行“> 1”操作的有效方式。它们也是目前执行交易的最佳方式。“某处”必须是柜台的唯一真实来源;如前所述,一个选项是 Redis,但正如我指出的那样,如果文档插入失败,这不是事务的一部分,它将回滚,这可能是也可能是不可接受的;例如,在事件溯源中,它不是。

于 2016-04-13T14:46:15.580 回答