2

我正在尝试做的事情:

  1. 我想将数据(id,数据)添加到 db。这样做时,我想检查 id 是否已经存在,如果存在,则附加到现有数据。否则添加一个新的 (id, data) 条目。

例如:这可能是多个测试中的学生 ID 和成绩的数据库。如果 db 中已经存在 id,我只想附加到 db 中已经存在的测试分数,否则创建一个新条目:(id,grades)

  1. 我已经设置了一个更新处理函数来执行此操作。我了解,couchdb insert 默认情况下不执行上述操作。现在 - 我如何检查数据库中的那个 id,如果是,决定是添加新条目还是追加。我知道有 db.get()。但是,我认为由于更新处理程序函数已经是 db itelf 的一部分,因此可能有一种更有效的方法。

我在 couchdb wiki 中看到了这个示例代码:

function(doc, req){
    if (!doc){
        if ('id' in req && req['id']){
            // create new document
            return [req, 'New Document'];
        }
        // change nothing in database
        return [null, 'Incorrect data format'];
    }
    doc[id] = req;
    return [doc, 'Edited World!'];
}

这个例子中有一些不清楚的说明:我们从哪里得到 id?在添加到 db 时,通常不会显式传入 id。

这是否意味着,我们需要显式传递一个名为“_id”的字段?

4

2 回答 2

1

如何检查数据库中的该 ID,如果是,则决定是添加新条目还是追加。

CouchDB 会为您执行此操作,假设 HTTP 客户端使用 ID 触发您的更新功能。如文档所述

当对更新处理程序的请求在 URL 中包含文档 ID 时,服务器将为函数提供该文档的最新版本

在您找到的示例代码中,更新函数看起来像这样function(doc, req),因此在该函数内部的代码中,变量doc将使现有文档已经“位于”您的 CouchDB 数据库中。来自客户端/用户的所有传入数据都将req.

因此,对于您的情况,它可能类似于:

function(doc, req){
  if (doc) {
    doc.grades.push(req.form.the_grade);
    return [doc, "Added the grade to existing document"];
  } else {
    var newDoc = {_id:req.uuid, grades:[req.form.the_grade]};
    return [newDoc, "Created new document ("+newDoc._id+") for the grade"];
  }
}

如果客户端执行 POST,/your_db/_design/your_ddoc/_update/your_update_function/existing_doc_id那么将触发第一部分,因为您将在变量if (doc)中获得现有文档(为您预取) 。doc如果客户端对 just 进行 POST /your_db/_design/your_ddoc/_update/your_update_function,则没有doc提供,您必须创建一个新的(else子句)。

请注意,客户端需要知道 ID 才能更新现有文档。要么跟踪它,查找它,要么——如果你必须理解它的缺点——根据已知的东西来确定它们。


另外:db.get()您提到的可能来自 CouchDB HTTP 客户端库,并且在任何更新/显示/列表/等的上下文中都不可用(并且不会工作)。在数据库“本身”中以沙盒方式运行的函数。

于 2018-11-28T01:46:43.537 回答
0

从文档中引用:

如果您正在更新现有文档,它应该已经设置了 _id,并且如果您正在创建新文档,请确保将其 _id 设置为基于输入或提供的 req.uuid 生成的某个值。第二个元素是将发送回调用者的响应。

所以tl;dr,如果未指定 _id ,请使用req.uuid.

文档链接:http ://docs.couchdb.org/en/stable/ddocs/ddocs.html#update-functions

于 2018-11-26T15:56:42.357 回答