前言
关于小程序使用云开发很多小伙伴有不少疑问,Q&A第二辑还是汇总了几个比较常见的问题,在这里一一为大家解答一下。
1、云开发数据库有哪些高级操作?
1、批量删除一个集合内的多条记录
我们在开发的过程中,一个集合内有几百条、几千条数据希望全部清空,但是又不想删掉该集合再重建,那应该如何做呢,总不能一条一条删除吧?云开发控制台的可视化操作目前无法做到批量删除一个集合内的多条记录的,但是这个功能我们可以通过控制台数据库高级操作的脚本来轻松进行批量删除,而且还可以创建一个脚本模板,有需要直接点击执行脚本模板做到长期复用。比如我们要删除集合为china的所有记录:
代码语言:javascript复制db.collection('china')
.where({
_id: _.exists(true)
})
.remove()
由于remove请求只支持通过匹配 where 语句来删除,我们可以在where里包含一个条件只要存在_id就删除,由于基本每个记录都有_id,所以就能都删除了。
2、如何给集合内所有数据都新增一个字段
我现在一个集合内有N条数据,由于数据库初期设计的问题,现在想给所有记录新增一个字段,想像进行关系型数据库和Excel新增一列的类似操作,那我应该怎么做呢?同样我们也可以通过控制台数据库高级操作的脚本。比如我们想给china集合内的所有记录都新增一个updateTime的字段,我们可以查询到需要新增字段的记录,然后使用update请求,当记录内没有updateTime字段就会新增:
代码语言:javascript复制const serverDate = db.serverDate
db.collection('china')
.where({
_id: _.exists(true)
})
.update({
data: {
updateTime: serverDate(),
}
})
3、如何让记录按照自己预想的方式来排序
我在小程序端批量上传了图片、文章,但是发现它们的显示顺序并不是按照我上传顺序来进行排序,但是我有不少功能却非常依赖排序这个功能,请问我应该怎么做?
批量上传或者你按时间上传,记录的排序并不会按照你认为的顺序来排序是很正常的,查询到的数据的顺序一般也不会是控制台数据库显示的顺序,这个都是非常正常的。你如果对排序有需求,有两种方式,一种是你在开发时就能设计好排序的字段,比如想让文章能按时间来排序,就应该在小程序发表文章时就设置一个字段来记录文章的发布时间,还有一种方式就是手动加字段来自定义,比如轮播的顺序,文章置顶或调整顺序这些,可能你还没有来得及开发相关功能,我们可以使用控制台来自定义,比如给你要排序的记录新增一个字段来自定义你想要的排序顺序,然后再在数据查询时使用orderBy。
云开发控制台的数据可视化管理和高级操作还可以实现很多类似于关系型数据库GUI管理工具的功能,毕竟GUI管理的背后就是数据库的脚本操作,更多功能大家可以自己多探索。
2、如何批量获取云存储的fileID以及批量导出数据库里所有数据?
我有很多图片、文件批量导入到了云存储,但是我批量获取这些文件的fileID应该怎么做?我的数据库有几十个集合,数据库经常需要备份,每次都要一个个导出非常麻烦,有没有好的方法?
如果大家有类似的功能,大家可以使用cloudbase-manager-node。cloudbase-manager-node的功能非常强大,里面有相比于tcb-admin-node更加丰富的接口,当然这些功能都需要开发人员可以结合接口进行一定的开发。
比如我们想批量获取云存储文件的fileID,可以使用listDirectoryFiles(cloudPath: string): Promise<IListFileInfo[]>
列出文件夹下所有文件的名称,也可以使用downloadDirectory(options): Promise<void>
来下载文件夹,比如我们想对所有集合的数据进行备份,可以使用listCollections(options: object): object
来获取所有集合的名称,然后使用export(collectionName: string, file: object, options: object): object
接口来导出所有记录到指定的json或csv文件里。
3、小程序云开发是否可以防止恶意刷资源?
小程序云开发的资源都是按照次数来付费的,特别担心我的云开发资源被人恶意刷从而影响业务进行或造成不必要的成本,这个应该怎么处理?
对于这个问题,开发者可以在小程序端做一些限制;云开发本身对单个微信用户的请求是有限流,超限部分是不算次数的,所以完全不必担心。
4、定时触发器怎么用?定时触发器为啥报错?为什么没有生效?
定时触发器可以处理周期性的事情,比如时报、日报、周报等通知提醒,也可以处理倒计时任务,比如节假日、纪念日以及你可以指定一个具体时间的倒计时任务,除此之外,定时触发器还可以用来周期性处理一些定时任务。比如定期清理一些不必要的数据,定期更新集合内的数据。
在使用定时触发器时,要注意以下问题:
1、要想让定时触发器少犯错误,以及可以定位到是不是触发器的问题,我们在对某个云函数使用触发器前,首先要保证该云函数在小程序端可以调用成功;
2、开发者工具的版本对触发器也存在影响这一点要注意。如果你要使用定时触发器来触发云调用,请保证你的开发者工具的版本是2019年10月18日之后的版本,目前官网最新的稳定版是没有问题的;
3、你的config.json文件是否配置正确,config.json文件可以用来配置权限和定时触发器,比如该云函数需要使用到订阅消息和内容安全两个权限,以及每5秒钟定时发送一次订阅消息,config.json的写法如下:
代码语言:javascript复制{
"permissions": {
"openapi": [
"subscribeMessage.send",
"security.imgSecCheck"
]
},
"triggers": [
{
"name": "tomylove",
"type": "timer",
"config": "*/5 * * * * * *"
}
]
}
config.json配置文件的格式,数组最后一项不能有逗号,
;配置文件里不能有注释等;Cron 表达式有七个必需字段,不能多也不能少;
4、务必要注意的是更新触发器文件和上传触发器两个概念的不同。当我们在修改触发器配置文件config.json后,首先鼠标右键config.json选择“云函数增量上传:更新文件”,然后再右键config.json选择“上传触发器”。这里的“云函数增量上传:更新文件”是让云函数端的触发器文件更新;而“上传触发器”则是让触发器开始生效执行。不能在云函数端的触发器没有更新的情况下就“上传触发器”来执行定时触发,因为你的文件没有更新,执行的还是旧的触发器内容。
5、聚合应该怎么使用?为什么我总是用不对?
聚合aggregate和数据查询get时不同的两套体系,聚合更偏向于数据的统计分析,用聚合来查询的功能非常强大,但是目前是不能对集合进行增、删、改等write的操作,因此所有结果都需要返回到小程序端。数据库查询的结果也必须限制在16MB以内。
由于聚合和数据查询都能对数据库进行查询,而且两个的很多方法都特别类似,所以很多人会混淆,甚至错误的混用,比如会在aggregate()加where条件、get请求,这里为了让大家更好理解,特整理一下两个的对比,大家写数据库查询和聚合时都可以先写类似以下的模板。
普通数据查询
代码语言:javascript复制const db = wx.cloud.database() //获取数据库的引用
const _ = db.command //获取数据库查询及更新指令
db.collection("china") //获取集合china的引用
.where({ //查询的条件指令where
gdp: _.gt(3000) //查询筛选条件,gt表示字段需大于指定值。
})
.field({ //显示哪些字段
_id:false, //默认显示_id,这个隐藏
city: true,
province: true,
gdp:true
})
.orderBy('gdp', 'desc') //排序方式,降序排列
.skip(0) //跳过多少个记录(常用于分页),0表示这里不跳过
.limit(10) //限制显示多少条记录,这里为10
.get() //获取根据查询条件筛选后的集合数据
.then(res => {
console.log(res.data)
})
.catch(err => {
console.error(err)
})
聚合查询
代码语言:javascript复制const db = wx.cloud.database()
const _ = db.command
const $ = db.command.aggregate
db.collection('china').aggregate()
.match({ //类似于where,对记录进行筛选
price: $.gt(3000)
})
.project({ //类似于field
})
.sort({ //类似于orderBy
age: -1,
score: -1
})
.skip(5) //类似于skip
.limit(2) //类似于limit
.end()
.then(res => console.log(res))
.catch(err => console.error(err))
- match是根据条件过滤文档,进行的是查询匹配,语法和where比较类似,在写聚合时,应尽可能的把match放在流水线的前面。match内可以写db.command查询操作符
_
和聚合操作符db.command.aggregate$
,但是除了match阶段,在其他聚合阶段中传入的对象可使用的操作符都是聚合操作符; - project 把指定的字段传递给下一个流水线,指定的字段可以是某个已经存在的字段,也可以是计算出来的新字段,它和field不同的是可以新增一些不存在的字段(只是显示用,也没写进数据库);
- sort 根据指定的字段,对输入的文档进行排序。<排序规则>可以是以下取值:1 代表升序排列(从小到大);-1 代表降序排列(从大到小);功能和orderBy类似;
- 小程序端 limit 默认 20,也就是如果你使用聚合查询,你查询到的数据都会默认显示20条数据,但是你可以设置更多,而普通查询是不能超过20条的
最后
为了可以更好地与云开发者交流,小助手会在「腾讯云云开发」公众号定期推送Q&A专题。欢迎大家在留言处提出疑惑或反馈问题,下期将为大家解答~
云开发(CloudBase)是一款云端一体化的产品方案 ,采用 serverless 架构,免环境搭建等运维事务 ,支持一云多端,助力快速构建小程序、Web应用、移动应用。
技术文档:https://www.cloudbase.net/
微信搜索:腾讯云云开发,获取项目最新进展