我们使用MarkLogic Server来存储一些运营应用程序数据,一个基本要求通常是某些元素值在数据库中的所有文档中都是唯一的(例如,应允许用户更改的电子邮件地址,但应该是在数据库中的所有用户中都是唯一的。有没有办法让MarkLogic Server确保这样的唯一性约束,无论数据库是如何写入的(即使用XQuery,ReST或XCC)?我们希望避免每个应用程序检查唯一性,因为这可能不安全且难以正确执行。
答案 0 :(得分:2)
我通常在这种情况下使用预提交触发器。它会减慢摄取速度,但是当某些检查不满意时,它可以很好地阻止插入的发生。在这种情况下,只需抛出一个错误(通过调用fn:error
),然后回滚更新。
要实际检查某个值是否尚未使用,您可以进行搜索(例如使用cts:search
或词典查找(例如使用cts:values
)。
您可以在伪uri(包括元素名称和值)上使用xdmp:lock-for-update
,以确保只有一个并发线程可以同时实际写入该值。其他人会等待或重启,并注意到该值。你只需要这个来进行高速摄取。
后者会导致争用,因此如果大量并发线程尝试声明相同的唯一值,则摄取可能会变慢。
HTH!
答案 1 :(得分:2)
你需要做某种检查。正如您所说,执行检查服务器端比客户端更有意义。
有很多方法可以做到这一点。以下是一些建议:
1)将地址合并到URI结构中,并且不为您的数据上传者提供文档更新权限。
创建一个URI结构,如:/data/normalizedAddress.xml。
不要为上传用户可以拥有的文档分配更新权限。
如果您尝试上传已使用该URI的文档,服务器将抛出无法更新现有文档的错误。
确保URI是使用诸如转换或自定义端点之类的东西在服务器端而不是客户端构建的。
2)使用cts:search或某个变体来查看该地址是否已存在于另一个文档中,然后抛出错误。