PouchDB数据库查询指南

在本系列文章的第三部分,将深入探讨PouchDB数据库的查询功能。PouchDB是一个NoSQL数据库,它允许在不依赖服务器的情况下存储和查询数据。在前两篇文章中,已经学会了如何创建数据库、修改文档以及使用allDocs()方法检索文档。现在,将学习如何使用find()插件来基于文档中的任何属性进行查询。

Mango查询

pouchdb-find插件可以在GitHub上下载。find()方法,也称为Mango查询,是一种结构化查询机制,允许在创建的二级索引上执行搜索。这种方法对于回答诸如“查找所有lastName为'sheriff'的文档”或“查找所有cost大于75的文档”这样的问题非常有用。需要下载pouchdb.find插件,并在HTML文件中添加对pouchdb-find.js文件的链接。

虽然不必在想查询的字段上创建索引,但如果不这样做,就会对所有文档进行完整的扫描。这取决于数据库中有多少文档,这可能是一个相当昂贵(且慢)的操作。如果知道最常查询的字段,就在这些字段上创建一个或多个索引。下面的代码示例展示了如何在lastName属性和cost属性上创建索引

function createIndexes() { // 在lastName上创建索引 db.createIndex({ index: { fields: ['lastName'] } }).then(function(response) { pouchDBSamplesCommon.displayJSON(response); }).catch(function(err) { pouchDBSamplesCommon.displayMessage(err); }); // 在cost上创建索引 db.createIndex({ index: { fields: ['cost'] } }).then(function(response) { pouchDBSamplesCommon.displayJSON(response); }).catch(function(err) { pouchDBSamplesCommon.displayMessage(err); }); }

如果尝试在没有索引的字段上进行排序,将会收到PouchDB的错误。如果在selector中使用的字段没有索引,那么默认索引(即_id字段)将被使用,并且将执行完整的文档扫描。PouchDB没有能力在没有该字段索引的情况下对数据进行排序,因此,会收到错误。

function showError() { // 注意:在排序字段上创建索引,否则会出错 db.find({ selector: { firstName: 'Paul' }, sort: ['firstName'] }).then(function(response) { pouchDBSamplesCommon.displayJSON(response); }).catch(function(err) { pouchDBSamplesCommon.displayMessage(err); }); }

如果在selector中使用了字段,但没有可用的索引,将在数据库中执行完整的文档扫描。数据将返回适当的文档选择,但会收到一个警告,表明没有找到匹配的索引。然后,可以决定是否创建一个。

function showWarning() { // 注意:如果在'selector'中使用了未索引的属性名称,会收到一个错误 db.find({ selector: { firstName: 'Paul' } }).then(function(response) { pouchDBSamplesCommon.displayJSON(response); }).catch(function(err) { pouchDBSamplesCommon.displayMessage(err); }); }

之前在lastName字段上创建了一个索引。现在可以通过在selector属性中指定lastName来使用该索引。可以通过包括fields属性来进一步限定返回的内容。这个属性是一个数组,包含了希望从这个查询中返回的文档中的属性名称。可以包括sort属性,但这实际上是不必要的。当使用索引时,文档将按索引顺序返回。

function findLastName() { db.find({ selector: { lastName: 'Sheriff' }, fields: ['_id', 'firstName', 'lastName'], sort: ['lastName'] }).then(function(response) { pouchDBSamplesCommon.displayJSON(response); }).catch(function(err) { pouchDBSamplesCommon.displayMessage(err); }); }

可以使用许多选择器操作符,而不仅仅是搜索完全匹配。选择器操作符以美元符号为前缀,包括:$eq$gt$gte$lt$lte$in。创建一个使用$in操作符的函数,以定位文档中的多个姓氏。下面的代码显示了搜索姓氏为'Sheriff'或'Jones'的文档。

function findLastNames() { pouchDBSamplesCommon.hideMessageAreas(); db.find({ selector: { lastName: { $in: ['Sheriff', 'Jones'] } }, fields: ['_id', 'firstName', 'lastName'] }).then(function(response) { pouchDBSamplesCommon.displayJSON(response); }).catch(function(err) { pouchDBSamplesCommon.displayMessage(err); }); }

另一个有用的选择器操作符是大于($gt)。之前在文档的cost属性上创建了一个索引,这些文档的docType为'service'。使用以下代码查找所有cost大于75的服务:

function greaterThan() { pouchDBSamplesCommon.hideMessageAreas(); db.find({ selector: { cost: { $gt: 75 } }, fields: ['_id', 'cost'] }).then(function(response) { pouchDBSamplesCommon.displayJSON(response); }).catch(function(err) { pouchDBSamplesCommon.displayMessage(err); }); } function searchTwoFields() { // 在两个字段上创建索引 db.createIndex({ index: { fields: ['docType', 'cost'] } }).then(function(response) { // 在两个字段上搜索 return db.find({ selector: { docType: 'service', cost: { $gt: 75 } }, fields: ['_id', 'cost'] }); }).then(function(response) { pouchDBSamplesCommon.displayJSON(response); }).catch(function(err) { pouchDBSamplesCommon.displayMessage(err); }); }
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485