美文网首页
PouchDB find() 配置'skip'注意事项

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

作者: CJ_景元 | 来源:发表于2021-03-13 22:58 被阅读0次

    背景

    最近客户端项目数据库替换成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,在计算跳过的时候会计入索引,在编写代码时如果遇到重复数据,需要留意了。

    相关文章

      网友评论

          本文标题:PouchDB find() 配置'skip'注意事项

          本文链接:https://www.haomeiwen.com/subject/ujhzqltx.html