65.9K
CodeProject 正在变化。 阅读更多。
Home

开始使用 PouchDB - 第 2 部分

starIconstarIconstarIconstarIconstarIcon

5.00/5 (3投票s)

2019 年 1 月 21 日

CPOL

5分钟阅读

viewsIcon

7871

在本系列的第二部分 PouchDB 中,您将学习如何执行多文档插入和读取。

在我上一篇关于 CodeProject.com 的文章中,您学会了在 PouchDB 数据库中插入、更新、删除和读取单个文档。现在让我们看看如何执行多文档插入和读取。 

批量操作

有几种不同的方法可以用来处理多个记录。下表总结了 PouchDB API 提供的每种方法。

方法 描述
bulkDocs() 创建、更新或删除多个文档
allDocs _id 字段检索多个文档。您还可以设置 _id 值范围进行检索。
bulkGet() 提供一组 _id_rev 值,此方法将返回与每个值关联的文档。

批量插入

要一次性将一组文档插入数据库,请使用 bulkDocs() 方法。创建一个您想插入的文档数组,然后将此数组传递给 bulkDocs() 方法。下面的代码显示了插入一组用户文档和一组服务文档。此多文档插入的结果是一个包含三个属性的 JSON 文档数组:okidrevok 属性值为“true”,id 具有您指定的原始 _id 值,rev 属性具有 PouchDB 生成的 _rev 字段。

function addMultipleDocs() {
  db.bulkDocs([
    {
      _id: 'psheriff',
      firstName: 'Paul',
      lastName: 'Sheriff',
      docType: 'technician'
    },
    {
      _id: 'bjones',
      firstName: 'Bruce',
      lastName: 'Jones',
      docType: 'technician'
    },
    {
      _id: 'jkuhn',
      firstName: 'John',
      lastName: 'Kuhn',
      docType: 'technician'
    },
    {
      _id: 'msheriff',
      firstName: 'Madison',
      lastName: 'Sheriff',
      docType: 'technician'
    },
    {
      _id: 'mshane',
      firstName: 'Molly',
      lastName: 'Shane',
      docType: 'technician'
    },
    {
      _id: 'Carpentry',
      cost: 100,
      docType: 'service'
    },
    {
      _id: 'Concrete',
      cost: 75,
      docType: 'service'
    },
    {
      _id: 'Yard work',
      cost: 25,
      docType: 'service'
    },
    {
      _id: 'Plumbing',
      cost: 75,
      docType: 'service'
    },
    {
      _id: 'Electrical',
      cost: 85,
      docType: 'service'
    }
  ]).then(function (response) {
    pouchDBSamplesCommon.displayJSON(response);
    pouchDBSamplesCommon.displayMessage("Multiple documents added.");
  }).catch(function (err) {
    pouchDBSamplesCommon.displayMessage(err);
  });
}

运行上述代码后,将返回类似以下的响应

[
  {
    "ok": true,
    "id": "psheriff",
    "rev": "1-3889989f75da4924a14e6551b8c8b4f0"
  },
  {
    "ok": true,
    "id": "bjones",
    "rev": "1-6959354560114b3aab4506af1f6ff89b"
  },
  {
    "ok": true,
    "id": "jkuhn",
    "rev": "1-a90aa8c09b514d4ba122643348e83f92"
  },
  ... // MORE DOCS HERE
]

如果在插入新文档时,任何 _id 值重复,将返回如下所示的错误响应文档

[
  {
    "status": 409,
    "name": "conflict",
    "message": "Document update conflict",
    "error": true,
    "id": "psheriff"
  },
  ... // MORE DOCS HERE
]

错误响应文档包含与成功响应不同的属性。status 属性设置为 HTTP 状态码,在本例中为 409name 属性设置为 HTTP 状态码的简短描述,在本例中为“conflict”。message 属性报告 PouchDB 遇到的问题的描述。error 属性始终设置为“true”。id 属性设置为有错误的文档 _id 属性。

批量更新

如果您想删除或更新一组文档,请将 JSON 对象数组传递给 bulkDocs() 方法。数组中的每个文档都需要将 _id_rev 属性设置为有效值。确保包含要更新的完整文档,否则它只会存储您包含的特定属性。

db.bulkDocs([
  {
    _id: 'psheriff',
    _rev: '1-bfe5495126ec488c8a707b50afb49bfe',
    firstName: 'Paul',
    lastName: 'Sheriff-CHANGED',
    docType: 'technician'
  },
  {
    _id: 'bjones',
    _rev: '1-65bfb049dbdc440bba314626cd17cbf5',
    firstName: 'Bruce',
    lastName: 'Jones-CHANGED ',
    docType: 'technician'
  }
]).then(function (response) {
  pouchDBSamplesCommon.displayJSON(response);
  pouchDBSamplesCommon.displayMessage("Multiple documents updated.");
}).catch(function (err) {
  pouchDBSamplesCommon.displayMessage(err);
});

批量删除

要删除一组文档,请传入一个 JSON 对象数组,其中包含 _id_rev 属性,并包含一个名为 _deleted 的属性,将其值设置为 true

db.bulkDocs([
  {
    _id: 'psheriff',
    _rev: '1-bfe5495126ec488c8a707b50afb49bfe',
    _deleted: true
  },
  {
    _id: 'bjones',
    _rev: '1-65bfb049dbdc440bba314626cd17cbf5',
    _deleted: true
  }
]).then(function (response) {
  pouchDBSamplesCommon.displayJSON(response);
  pouchDBSamplesCommon.displayMessage("Multiple documents deleted.");
}).catch(function (err) {
  pouchDBSamplesCommon.displayMessage(err);
});

allDocs() 方法

PouchDB 数据库检索文档的最佳方法之一是使用 allDocs() 方法。allDocs() 方法使用基于文档 _id 属性值创建的自动索引。allDocs() 方法允许您检索数据库中的全部文档或部分文档。使用 allDocs() 方法检索的文档按 _id 顺序返回。让我们看看如何调用不带参数的 allDocs() 方法。

function getAllDocIdsAndRevs() {
  db.allDocs().then(function (response) {
    pouchDBSamplesCommon.displayJSON(response);
  }).catch(function (err) {
    pouchDBSamplesCommon.displayMessage(err);
  });
}

allDocs() 返回的响应包含三个属性。“total_rows”属性报告此数据库中的文档数量。“offset”属性报告您是否在“rows”属性中提供行之前跳过了任何文档。“rows”属性是一个 JSON 对象数组,其中包含“id”、“key”和“value”属性。idkey 属性包含 _id 属性的原始值。value 属性是一个具有单个名为“rev”的属性的对象。此值是 PouchDB 生成的 _rev 属性。

{
  "total_rows": 10,
  "offset": 0,
  "rows": [
    {
      "id": "bjones",
      "key": "bjones",
      "value": {
          "rev": "1-65bfb049dbdc440bba314626cd17cbf5"
       }
     },
     {
       "id": "jkuhn",
       "key": "jkuhn",
       "value": {
          "rev": "1-30b056415cdd4ec69843ec3979c83702"
       }
     },
     ... // MORE DOCS HERE
  ]
}

虽然上述数据提供了使用 get() 方法检索任何文档的必要信息,但您可能希望使用 allDocs() 获取所有文档数据。将一个 *options* 对象传递给 allDocs() 方法来控制此方法的返回值。*options* 对象有许多可以设置的属性。对于此示例,只需将 include_docs 属性设置为 true,以告诉 allDocs() 返回完整的文档数据。

function getAllDocuments() {
  db.allDocs({ include_docs: true }).then(function (response) {
    pouchDBSamplesCommon.displayJSON(response);
  }).catch(function (err) {
    pouchDBSamplesCommon.displayMessage(err);
  });
}

计算文档数量

如您在上面的响应对象中所见,您总是会收到 total_rows 属性。如果您只想获取文档总数,而不获取所有文档数据,请将选项对象中的两个属性设置为以下值:limit:0include_docs: false

function countDocuments() {
  db.allDocs({
    limit: 0, 
    include_docs: false 
  }).then(function (response) {
    pouchDBSamplesCommon.displayJSON(response);
  }).catch(function (err) {
    pouchDBSamplesCommon.displayMessage(err);
  });
}

此查询的结果将是一个如下所示的响应对象

{
    "total_rows": 10,
    "offset": 0,
    "rows": []
}

注意total_rows 属性始终是数据库中的文档总数。

按范围获取

由于每次将文档插入 PouchDB 数据库时都会自动创建索引,因此这意味着您可以使用 _id 属性过滤数据。在 *options* 对象中包含两个属性,startkeyendkey,并指定开始值和结束值。请看下面的代码

function getByRange() {
  let options = {
    include_docs: true,
    startkey: 'bjones',
    endkey: 'jkuhn'
  }
  // Get the data
  db.allDocs(options).then(function (response) {
    pouchDBSamplesCommon.displayJSON(response);
  }).catch(function (err) {
    pouchDBSamplesCommon.displayMessage(err);
  });
}

startkey 属性设置为一个 id 'bjones',endkey 属性设置为一个在 id 排序顺序中稍后的。返回两个键之间(包括这两个键)的所有文档。

按部分键获取

startkeyendkey 不需要包含完整的 id 值;您也可以根据部分数据进行搜索。例如,请看以下代码

function getByPrefix() {
  pouchDBSamplesCommon.hideMessageAreas();
  let options = {
    include_docs: true,
    startkey: 'msh',
    endkey: 'msh\ufff0'
  }
  // Get the data
  db.allDocs(options).then(function (response) {
    pouchDBSamplesCommon.displayJSON(response);
  }).catch(function (err) {
    pouchDBSamplesCommon.displayMessage(err);
  });
}

在选项对象中,startkey 属性设置为 'msh',因此它将匹配如 'msheriff' 或 'mshane' 等文档。endkey 属性包含字符串 'msh\ufff0'。值 '\ufff0' 是一个特殊的 Unicode 高位字符,表示排序顺序中的最后一个值。对于此示例,这相当于为 endkey 属性指定 'mshzzzzzzzzzz'。此示例允许您检索仅以 'msh' 开头的任何记录。

摘要

在本系列的第二部分关于 PouchDB 的博客文章中,您学会了从数据库批量插入、更新和删除文档。此外,您还学会了使用 allDocs() 方法检索和计数文档。

© . All rights reserved.