【问题标题】:How to check for duplication before creating a new document in CouchDB/Cloudant?在 CouchDB/Cloudant 中创建新文档之前如何检查重复?
【发布时间】:2018-01-30 19:20:20
【问题描述】:

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

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

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

目前的想法是:

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

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

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

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

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

【问题讨论】:

  • 我们在谈论大文件吗?您是否有任何文件样本可以帮助我们提出想法?你总是可以创建一个散列形式的文档内容。
  • 有些很小,有些很大,比如 30 个属性用于较大的属性.. 但实际上我们可能不需要进行深入比较.. 对于我们的用例来说可能就足够了,只需比较以下属性即可文档根级别的简单字段(不是 obj 或数组)。

标签: couchdb cloudant couchdb-mango


【解决方案1】:

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

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

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

头 /db/docId

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

如果您想检查新文档和前一个文档中是否有相同的内容,您可以使用Validate Document Update Function 允许比较两个文档。

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

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

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

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

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

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

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

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

  • 在创建新文档之前,您应该使用之前需要计算的哈希来查询视图。

【讨论】:

  • 我不想做任何这些事情。 ID 是不同的,因为它是一个新文档 [注意我在问题中特别说“减去 _id 字段”] 而且这不是补丁/更新操作,它是一个正在插入的新文档,我需要与现有文档进行比较数据库中的文档。
  • 您可以选择根据那些应该唯一的属性值计算哈希并将其添加到文档中?
  • 也许,我只是还没有听说过这个解决方案。您能否指出在避免 noSQL 数据库中的重复的上下文中使用它的任何链接/示例?
  • 还没有看过如何使用选项 3,但我真的很喜欢选项 2。唯一的缺点似乎是竞争条件:我允许/拒绝基于先前状态的插入同时可能发生变化的数据库......但这也许是平台的限制?
  • 也许您可以根据一个视图执行清理过程,该视图计算您存储了多少具有相同哈希的文档。
【解决方案2】:

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

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

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

【讨论】:

  • 该检查应该在所有字段上运行,这不是对特定字段的检查,所以这就是我们不想使用 ID 来存储哈希的原因。话虽如此,将哈希存储在另一个专用字段中似乎是最可行的选择
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多