PouchDB客户端JavaScript数据库入门

Sebastian SeitzTaulant Spahiu对此文章进行了同行评审。 感谢所有SitePoint的同行评审人员使SitePoint内容达到最佳状态!

近年来,客户端Web应用程序变得越来越复杂。 浏览器一直以来都提供更好的JavaScript性能,并且能够使用丰富的JavaScript API(例如地理定位和点对点通信)来做越来越多的事情。

富Web应用程序的兴起也带来了对良好的客户端存储机制的需求,这就是JavaScript数据库(如PouchDB)应运而生的地方。

什么是PouchDB?

PouchDB是一个受Apache CouchDB启发的开源JavaScript数据库,旨在在浏览器中良好运行。

什么是JavaScript数据库?

简单来说,JavaScript数据库是一个JavaScript对象,它提供用于放置,获取和搜索数据的方法(或API)。 实际上,一个普通的旧JavaScript对象是最简单的JavaScript数据库。 如果您熟悉Meteor ,那么您可能听说过Minimongo ,它是另一个模仿MongoDB API的客户端JavaScript数据库。

PouchDB是CouchDB的JavaScript实现。 它的目标是在浏览器或Node.js中运行时,以接近完美的保真度模拟CouchDB API。

PouchDB与Minimongo这样的数据库的不同之处在于,默认情况下,它不仅是内存中的,它还在后台使用IndexedDB进行存储。 IndexedDB是用于客户端存储大量结构化数据(包括文件/ blob)的低级API。 这意味着PouchDB数据存储在磁盘上,并且即使在页面刷新后仍然可用(但是,一个浏览器存储的数据将对其他浏览器不可用)。

不同的适配器使您可以更改基础数据存储层。

与CouchDB的关系

PouchDB是CouchDB的JavaScript实现,并尽可能接近其API。

在CouchDB中,您将使用此API调用获取所有文档

/db/_all_docs?include_docs=true

在PouchDB中,它变成

db.allDocs({include_docs: true})

PouchDB使应用程序可以在脱机时在本地存储数据,然后在应用程序恢复在线时将其与CouchDB同步。

现在,让我们看看如何在应用程序中使用PouchDB。

安装

要开始使用PouchDB,您只需要包括PouchDB客户端库。 您可以使用独立的构建,这使PouchDB构造函数在window对象上全局可用

<script src="https://cdn.jsdelivr.net/pouchdb/5.4.5/pouchdb.min.js"></script>

或者,如果您在Node.js / browserify / webpack环境中使用它,则可以使用npm进行安装。

$ npm install pouchdb --save

然后在您的JavaScript中:

var PouchDB = require('pouchdb');

(有趣的事实: npm isntall pouchdb也可以使用!)

使用PouchDB

建立资料库

创建PouchDB数据库就像调用PouchDB构造函数一样简单。 让我们创建一个名为“电影”的数据库。

var movies = new PouchDB('Movies');

运行之后,您可以使用info方法查看有关数据库的基本信息,该方法返回Promise

movies
 .info()
 .then(function (info) {
   console.log(info);
 })

上面的代码输出以下内容:

{"doc_count":0,"update_seq":0,"idb_attachment_format":"binary","db_name":"Movies","auto_compaction":false,"adapter":"idb"}

adapter字段指示其下方正在使用IndexedDB。

处理文件

PouchDB是基于文档的NoSQL数据库,因此没有严格的架构,您可以直接插入JSON文档。 让我们看看如何插入,更新,检索或删除文档。

建立文件

您可以使用put方法创建一个新文档

// returns a promise
db.put(doc, [docId], [docRev], [options])

方括号中的参数是可选的。 每个文档都有一个与它关联的_id字段,它用作唯一标识符。

通过运行以下代码,在以前创建的Movies数据库中创建一个新文档:

movies
  .put({
    _id: 'tdkr',
    title: 'The Dark Knight Rises',
    director: 'Christopher Nolan'
  }).then(function (response) {
    console.log("Success", response)
  }).then(function (err) {
    console.log("Error", err)
  })

在成功的情况下,响应将类似于:

Success {ok: true, id: "tdkr", rev: "3-f8afdea539618c3e8dceb20ba1659d2b"}

现在调用movies.info()将给出{doc_count: 1}以及其他数据,表明我们的文档确实已插入。

响应中的rev字段指示文档的修订。 每个文档都有一个名为_rev的字段。 每次更新文档时,文档的_rev字段都会更改。 每个修订版均指向其先前的修订版。 PouchDB维护每个文档的历史记录(类似于git)。

阅读文件

PouchDB提供了一种get API方法,用于通过其ID检索文档。 运行:

movies
  .get('tdkr')
  .then(function(doc) {
    console.log(doc)
  })
  .catch(function (err) {
    console.log(err)
  })

会给像

{title: "The Dark Knight Rises", director: "Christopher Nolan", _id: "tdkr", _rev: "3-f8afdea539618c3e8dceb20ba1659d2b"}
更新文件

假设我们要在文档中添加一个“年份”字段。 您可以通过运行以下命令来更新上面创建的文档:

movies
  .get('tdkr')
  .then(function(doc) {
    doc.year = "2012"    // new field
    console.log(doc._rev) // doc has a '_rev' field
    return db.put(doc)   // put updated doc, will create new revision
  }).then(function (res) {
    console.log(res)
  })

更新文档时,必须提供_rev字段。

您应该在控制台中看到类似的输出:

{ok: true, id: "tdkr", rev: "4-7a34189fb8f2e28fe08b666e699755b8"}

指示文档的新修订版。

删除文件

在PouchDB中删除文档只是将其_deleted属性设置为true 。 您可以调用.remove()来做到这一点:

movies
  .get('tdkr')
  .then(function(doc) {
    return movies.remove(doc) // return the promise
  }).then(function(res) {
    console.log("Remove operation response", res)
  })

等同于做

movies
  .get('tdkr')
  .then(function (doc) {
    doc._deleted = true
    return db.put(doc)
  })
  .then(...)

删除数据库

您可以通过在db对象上调用destroy()来删除数据库。

// returns a promise
movies.destroy() 

批量操作

到目前为止,我们一直使用PouchDB中的单个文档。 但是,它还提供了用于处理文档集合的API。 PouchDB提供了两种用于批量操作的方法bulkDocs()用于批量写入,以及allDocs()用于批量读取。

bulkDocs()方法非常简单。 它只需要将一系列文档插入数据库。

插入多个文件

// Returns a promise
movies.bulkDocs([
  {
    _id: 'easy-a',
    title: "Easy A",
    // other attribues
  },
  {
    _id: 'black-swan',
    title: 'Black Swan',
    // ...
  }
])

样本响应:

[
  {
    "ok": true,
    "id": "easy-a",
    "rev": "1-84abc2a942007bee7cf55007cba56198"
  },
  {
    "ok": true,
    "id": "black-swan",
    "rev": "1-7b80fc50b6af7a905f368670429a757e"
  }
]

如果要插入多个文档,则使用批量API通常比执行多个put()请求更好。 批量操作往往比单个操作要快,因为它们可以组合为单个事务(对于本地IndexedDB / WebSQL存储)或单个HTTP请求(对于远程CouchDB服务器)。

检索多个文件

要阅读多个文档,PouchDB提供了allDocs()方法。

// without {include_docs: true}, only document ids are returned
movies
  .allDocs({include_docs: true})
  .then(function (docs) {
    console.log(docs)
  })

这是一种快速且非常有用的方法。 从PouchDB文档中:

allDocs()是PouchDB世界的无名小卒。 它不仅可以按顺序返回文档,还可以颠倒顺序,使用_id进行过滤,使用_id上的“大于”和“小于”操作对切片和切成小方块,等等。

默认情况下,文档以_id升序返回。 您可以指定{descending: true}以颠倒顺序。

movies
  .allDocs({
    include_docs: true, 
    descending: true
  })
  .then(...)

您还可以指定startkeyendkey参数以获取一定范围内的文档。 例如,要获取所有_id以'a'或'b'开头的电影,可以运行以下查询:

movies
  .allDocs({
    include_docs: true,
    startkey: 'a',
    endkey: 'c'
  })
  .then(console.log)
  .catch(console.log)

startKeyendKey参数对于分页API尤其有用。

通过ChangeFeeds实时进行

我们讨论了PouchDB如何使用_rev字段来跟踪修订,每个修订都指向先前的修订。 PouchDB和CouchDB使用此修订版链进行数据库复制。

但是,此复制算法的含义是,它允许您查看数据库的历史记录,从而使您可以回答诸如

  • 自给定时间以来,对数据库进行了哪些更改?
  • 对特定文档进行了哪些更改?

这是changes() API出现的地方。

要获取自时间开始以来的所有更改:

db.changes({
  since: 0,
  include_docs: true
}).then(function (changes) {
  console.log(changes)
}).catch(...)

但是,在Web应用程序中,您通常对查看在初始页面加载后发生的数据库更改更感兴趣,因此您可以相应地更改UI。 PouchDB / CouchDB二人组还为您提供了实时更改提要。

db
  .changes({
    since: 'now',
    live: true,
    include_docs: true
  })
  .on('change', function (change) {
    // This is where you can modify UI, based on database change.
    // change.id contains the doc id, change.doc contains the doc
    if (change.deleted) {
      // document was deleted
    } else {
      // document was added/modified
    }
  })
  .on('error', function (err) {
    // handle errors
  })

因此,如果您有一个基本的列表应用程序,则可以在一个窗口中添加项目,它们会实时显示在另一个窗口中。

您可以看到此操作演示

同步:使PouchDB数据超越浏览器

大多数应用程序需要将数据存储在后端,而不仅仅是在浏览器中,因此您可以使用PouchDB在本地存储数据,但可以将其与后端CouchDB实例同步,以便数据可以在任何地方使用,而不仅仅是在该特定的浏览器中。

PouchDB提供了一个非常简单的API来执行此操作。 假设您已经建立了一个远程CouchDB数据库,只需两行JavaScript就可以同步它。

// local database, that lives in the browser's IndexedDB store
var localDB = new PouchDB('mylocaldb')

// remote CouchDB 
var remoteDB = new PouchDB('http://localhost:5984/myremotedb')

您可以通过以下方式将本地更改复制到远程数据库:

localDB
  .replicate
  .to(remoteDB)
  .on('complete', function () {
    // local changes replicated to remote
  }).on('error', function (err) {
    // error while replicating
  })

但是,由于许多用户可能都可以访问同一数据库,因此能够将更改从远程数据库同步到浏览器更加有用。 PouchDB也为您提供服务。

可以使用以下一行JavaScript来实现双向同步:

// replicates once
localDB.sync(remoteDB);

或进行实时同步:

// keeps syncing changes as they occur
localDB.sync(remoteDB, {live: true})

下一步

PouchDB还具有不断增长的插件和框架适配器生态系统,我们没有足够的空间来使用这些插件和框架适配器 ,但是绝对值得一试。 另外,在使用PouchDB时,您可以使用PouchDB Inspector chrome扩展,它提供了一个漂亮的GUI来查看您的数据库。

这就是PouchDB的介绍性介绍。 它绝对是那里更有趣的数据库之一,我希望您能看到如何使用它来构建脱机优先的实时应用程序。

From: https://www.sitepoint.com/getting-started-with-pouchdb/

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值