jql联表查询涉及到权限的最好用上临时表

JQL联表查询的两种方法

联表查询

为方便文档描述定义以下两个概念:

  • 临时表:getTemp方法返回的结果,例:const article = db.collection('article').getTemp(),此处 article 就是一个临时表
  • 虚拟联表:主表与副表联表产生的表,例:db.collection(article, 'comment').get()

JQL于2021年4月28日优化了联表查询策略,详情参考:联表查询策略调整

JQL提供了更简单的联表查询方案。不需要学习join、lookup等复杂方法。

只需在db schema中,将两个表的关联字段建立映射关系,就可以把2个表当做一个虚拟联表来直接查询。

JQL联表查询有以下两种写法:

// 直接关联多个表为虚拟联表再进行查询,旧写法,目前更推荐使用getTemp进行联表查询
const res = await db.collection('order,book').where('_id=="1"').get() // 直接关联order和book之后再过滤

// 使用getTemp先过滤处理获取临时表再联表查询,推荐用法
const order = db.collection('order').where('_id=="1"').getTemp() // 注意结尾的方法是getTemp,对order表过滤得到临时表
const res = await db.collection(order, 'book').get() // 将获取的order表的临时表和book表进行联表查询

复制代码

上面两种写法最终结果一致,但是第二种写法性能更好。第一种写法会先将所有数据进行关联,如果数据量很大这一步会消耗很多时间。

1. 这种jql查出来是空数组

db.collection('opendb-poi,uni-id-users').where(`"user_id"==$env.uid`).field("user_id._id,name").get()

原因:

JQL数据库操作 | uniCloud

权限校验

要求组成虚拟联表的各个临时表都要满足权限限制,即权限校验不会计算组合成虚拟联表之后使用的where、field

以下为一个订单表(order)和书籍表(book)的schema示例

// order schema
{
  "bsonType": "object",
  "required": [],
  "permission": {
    "read": "doc.uid==auth.uid",
    "create": false,
    "update": false,
    "delete": false
  },
  "properties": {
    "id": { // 订单id
      "bsonType": "string"
    },
    "book_id": { // 书籍id
      "bsonType": "string"
    },
    "uid": { // 用户id
      "bsonType": "string"
    }
  }
}

// book schema
{
  "bsonType": "object",
  "required": [],
  "permission": {
    "read": true,
    "create": false,
    "update": false,
    "delete": false
  },
  "properties": {
    "id": { // 书籍id
      "bsonType": "string"
    },
    "name": { // 书籍名称
      "bsonType": "string"
    }
  }
}

复制代码

如果先对主表进行过滤where('uid==$cloudEnv_uid'),则能满足权限限制(order表的"doc.uid==auth.uid"

const order = db.collection('order')
.where('uid==$cloudEnv_uid') // 先过滤order表内满足条件的部分
.getTemp()

const res = await db.collection(order, 'book').get() // 可以通过权限校验

如果不对主表过滤,而是对虚拟联表(联表结果)进行过滤,则无法满足权限限制(order表的"doc.uid==auth.uid"

const order = db.collection('order').getTemp()

const res = await db.collection(order, 'book').where('uid==$cloudEnv_uid').get() // 对虚拟联表过滤,无法通过权限校验

2. 用这种的方式查还是报错:

let where = '"user_id" == $env.uid'

let opendbPoi_temp = db.collection('opendb-poi').where('"user_id"==$env.uid').getTemp()

const res = await db.collection(opendbPoi_temp,'uni-id-users').where(where).field(
						"user_id.avatar_file as avatar_file,user_id._id,_id,title,tel,address,name").get()

console.log('res73', res);

3.上面这种写法确实问题很大,但是改成这种还是报错

后面改成这种就好了,联表查询涉及到权限的最好用上临时表

const db = uniCloud.database();
let opendbPoi_temp = db.collection('opendbpoi').where('"user_id"==$cloudEnv_uid').getTemp()
				console.log('opendbPoi_temp3', opendbPoi_temp);
let uniIdUsers_temp = db.collection('uni-id-users').field("_id,avatar_file").getTemp()
const res = await db.collection(opendbPoi_temp, uniIdUsers_temp).field(
					"user_id.avatar_file as avatar_file,user_id._id,_id,title,tel,address,name").get()
				console.log('res77', res);

附带另外一篇别人写的涉及unicloud-db 联合查询的文章


 where='project_id.is_show=="show"' 副表的数据需要满足的条件

project_id 主表关联副表的主键

<unicloud-db ref='udb' v-slot:default="{data,pagination,hasMore, loading, error, options}" @error="onqueryerror"
                 :page-size="10" @load="resultData"
                     :collection='colList'
                     where='project_id.is_show=="show"'
    >
</unicloud-db>
 


 
 官方解释:联表查询有以下两种写法,对于数据量稍大的表推荐使用多个临时表组成的数组作为collection,可以在主表的getTemp内先进行过滤减小联表时的性能消耗。

就是先过滤主表,减少数据,然后再联表

colList(){
      return [
        db.collection('bank-project-manage-auth-user').where('"user_id"==$env.uid').field('user_id,project_id').getTemp(),
        db.collection('bank-project-manage-project').where('"is_show"=="show"').field('_id,name,cooperation_name,status,start_time,latest_evaluation,is_show').getTemp()
      ]
}

                            版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
                        
原文链接:https://blog.csdn.net/u013732449/article/details/129152484

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值