0

我们想检查数据库中是否已经存在与我们试图保存的新对象的相同字段和值的文档,以防止重复项目。

注意:此问题与更新文档或重复文档 ID 无关,我们仅检查数据以防止保存与现有文档具有相同数据的新文档。

最好我们希望通过 Mango/Cloudant 查询来完成此任务,而不是依赖视图。

到目前为止的想法是:

1)扫描我们试图保存的数据并动态创建一个匹配该文档结构的选择器。(我们不能硬编码选择器,因为我们有很多文档的类型)

2) 如果已经存在与这些条件匹配的任何文档,则查询与该选择器匹配的任何文档的 de DB。

但是我想知道这种方法的性能,因为许多选择器字段不会被索引。

我也更愿意遵循最佳实践,而不是突然创造一些东西,但我无法为这个特定场景找到任何已知的解决方案。

如果你碰巧知道,请分享。

4

2 回答 2

0

选项 1 - 为您的文档定义一个有意义的 ID

ID 可以是一个逻辑组合,也可以是从应该唯一的值中计算出来的哈希值

如果要检查文档 ID 是否已存在,可以使用 HEAD 方法

头 /db/docId

如果 docId 在数据库中存在,则返回 200-OK。

如果您想检查新文档和前一个文档中是否有相同的内容,您可以使用验证文档更新功能,该功能允许比较两个文档。

function(newDoc, oldDoc, userCtx, secObj) {
...
}

选项 2 - 使用在 CouchDB 之外计算的内容哈希

  • 在创建或更新文档之前,应该使用应该唯一的属性值来计算哈希值。

  • 哈希包含在文档中的一个新属性中,即“key_hash”

  • 使用“key_hash”属性创建芒果索引

  • 当应该插入一个新文档时,应该在插入文档之前使用芒果表达式计算并查找具有相同哈希值的文档的哈希值。

选项 3 - 在视图中计算哈希

  • 定义一个视图,它为每个文档发出计算的哈希作为键

    • Couchdb Javascript 支持不包括散列函数,这可能很难包含在设计文档中。
    • 使用erlang 定义 map 函数,您可以在其中访问 erlang 对散列的支持。
  • 在创建新文档之前,您应该使用之前需要计算的散列来查询视图。

于 2018-01-30T20:22:03.447 回答
0

一种解决方案是将 Juanjo 和 Alexis 的评论更进一步。

  1. 选择您希望保持唯一的键
  2. 将值放入字符串并生成哈希
  3. 将文档的 _id 设置为该哈希
  4. 将文档放在数据库中。
  5. 检查返回失败

如果数据库中已存在具有相同 _id 值的另一个文档,则 PUT 请求将失败。

于 2018-01-31T18:16:40.003 回答