2

我们使用 MarkLogic Server 来存储一些操作应用程序数据,一个基本要求通常是某些元素值在数据库中的所有文档中是唯一的(例如,应该允许用户更改的电子邮件地址,但在所有文档中应该是唯一的数据库中的用户)。有没有办法让 MarkLogic Server 确保这种唯一性约束,而不管数据库是如何写入的(即使用 XQuery、ReST 或 XCC)?我们希望避免检查每个应用程序的唯一性,因为这可能不安全且难以正确执行。

4

2 回答 2

2

对于这种情况,我通常使用预提交触发器。它会稍微减慢摄取速度,但是当某些检查不满意时,它可以很好地阻止插入发生。在这种情况下,只需抛出一个错误(通过调用fn:error),更新就会回滚。

要实际检查一个值是否尚未使用,您需要进行搜索(例如使用cts:search或词典查找(例如使用cts:values)。

您可以xdmp:lock-for-update在假 uri(包括元素名称和值)上使用,以确保只有一个并发线程可以同时实际写入该值。其他人将等待或重新启动,并注意取值。你只需要这个来进行高速摄取。

后者会导致争用,因此如果大量并发线程试图声明相同的唯一值,摄取可能会减慢。

于 2018-06-08T12:57:25.263 回答
2

你需要做一些检查。正如您所说,在服务器端执行检查比在客户端执行检查更有意义。

有很多方法可以做到这一点。这里有几个建议:

1) 将地址合并到 URI 结构中,并且不要授予您的数据上传者文档更新权限。

创建一个 URI 结构,如:/data/normalizedAddress.xml。

不要将更新权限分配给上传用户可以拥有的文档。

如果您尝试上传已使用该 URI 的文档,服务器将抛出您无法更新现有文档的错误。

确保 URI 是在服务器端构建的,而不是在客户端使用转换或自定义端点之类的东西。

2) 使用 cts:search 或一些变体来查看该地址是否已经存在于另一个文档中,如果存在则抛出错误。

于 2018-06-08T13:01:57.473 回答