PouchDB find() 配置'skip'注意事项

背景

最近客户端项目数据库替换成PouchDB(v7.2.2),在转移分页功能时遇到了问题。

场景

考虑性能和拓展空间,采用 db.allDocs()作为批量查询方法,用skiplimit参数实现分页,例如:

let skipNum = 0;
db.allDocs({
    limit: 50, // page size
    skip: skipNum,
  }).then(res => {
    const { rows } = res;
    ......
    skipNum += rows.length; // skip loaded data
  });
});

首页加载异常,检查返回的rows里包含了创建的索引原来是在之前测试时无意中创建了索引(db.createIndex()索引_id_design/idx-开头,查询得知db.allDocs()方法会返回数据库所有数据,且索引也存储在业务数据”表“中,这就导致返回数据包含了`索引,不是期望的结果

个人觉得索引这种业务无关数据不应该放入这张"表",违反直觉

那么删除索引,此时返回如预期一样,返回业务数据,并且最大数据按照limit限制来返回。


如果搜索必须依赖索引,而索引与业务数据同一个数据库,怎么办呢?

这个数据库有另一个跟直觉相悖的地方,假定搜索字段必须要创建索引才能实现,这次使用db.find()来使用索引

let skipNum = 0;
// db内假定是如此[1,2,3,4,5],5条业务数据
db.createIndex({
  index: {fields: ['_id']} // 对内部属性建立索引
}).then(function () {
/* 
  创建索引后,db内数据条数已经是6, 使用db.info()和db.allDocs()获取数据长度皆为6。
  但是db.find()获取的长度还是5,看来已经过滤掉索引数据,很棒。
**/
  return db.find({
    selector: {_id: {$gt: null}},
    limit: 50, // page size
    skip: skipNum,
  }).then(res => {
    const { docs } = res.docs;
    ......
    skipNum += docs.length; // skip loaded data
    /* 
      dosc.length等于5,
      所以加载下一页时,skipNum等于5,跳过5条,应该返回docs等于[]才是预期,可实际上?
    **/
  });
});

实际上返回一个包含一条数据的数组。猜想在skip时,db.find()方法还是把索引计入了。这就是上文返回重复的根本原因。

这非常让人迷惑,返回数据不含索引,但是skip跳过数据又计算了索引

结论

不使用索引或者只需要搜索内部属性_id的,不需要db.createIndex(),这样即使需要分页使用skip也没有影响。
需要索引,且需要分页的,db.find()不会返回索引数据到结果中,但是注意skip,在计算跳过的时候会计入索引,在编写代码时如果遇到重复数据,需要留意了。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容