轻服务与nodejs踩坑综合记

229 阅读2分钟

轻服务与nodejs踩坑综合记

  • 关于当想使用一个数组作为轻服务接口的request params,想使用这个数组从数据库中查出所有对应的observations的方法。

    • 一个例子

      • 当我们传入的是一个由要查询的observations的id字段组成的数组

        {
          "idList": [
            "2375360734846391",
            "1495755366941576",
            "1600525133428039",
            "1846782829803550"
          ]
        }
        
      • 目的是从数据库中查出所有对应id字段的observation

    • 针对这个例子,利用轻服务提供的where完成查询的方法

      • 需要注意的是,轻服务的where不接受直接提供数组

        const resList = await table.where(idList).find(); //这样是查不成功的。
        
      • 首先,我们可以想到一个简单的方法——for循环

        const resList = [];
        for(let i = 0;i < idList.length;i++)
        {
          const list = await table.where({id: idList[i]}).find();
          resList.push(...list);
        }
        

        但是明显的缺陷无法利用API一次性从数据库查出数据,需要很多次数组操作

      • 接下来,我们尝试是否可以使用一些取巧的方法一次性查询所有数据。

        • 首先我们注意到,轻服务的whereAPI支持传入一个函数

          function query(idList){
            return idList.includes(this.id);
          }
          const list = await table.where(query(idList)).find()
          

          但是我们尝试之后,很快发现是不行的,错误在于,一旦传入参数,那么函数中的this就不再指向数据中的observation了

        • 为了不传入参数,但是可以引用到idList,我们很容易想到使用闭包

          function query(idList){
            return function(){
              return idList.includes(this.id)
            }
          }
          const list = await table.where(query(idList)).find();
          

          闭包可以让传入where的闭包函数在即使外层函数已经执行完毕被销毁的情况下,依旧可以访问到外层函数作用域中的变量。

          但是我们发现由于轻服务对闭包变量进行了处理,使内部函数无法访问到闭包变量。

        • 接下来,经过再次仔细阅读文档,我们可以发现,轻服务中如果想要查询多个filter的话

          const list = await table.where(db.or(filter1,filter2,...)).find();
          

          这样我们似乎可以将多个filter组成一个数组,利用展开运算符传入db.or()

          function query(list){
            const filterList = list.map((item) => {return {id: item}});
            return filtereList;
          }
          const list = await table.where(db.or(...query(idList));
          

          很快,最终使用这个方法成功了。