云数据库

官方文档
这是一种NoSQL数据库, 具体是哪种则没有讲.
我感觉NoSQL和SQL在使用上的最大区别是字段的数据类型. NoSQL可以添加Object和Array类型的字段. 然而相同点在于, 无论什么字段类型,每次查询到的都是整条记录(NoSQL叫做Doc文档),而不可能查询Array或Object字段内的子元素.
由于有Array/Object字段, 可以选择其中的子元素作为查询条件, 或者只更新子元素的值.
通过微信开发者工具云开发->数据库建立一个集合,相当于是一张表.

数据类型

除了常规js类型string/number/boolean/array/object以外, 还有1个略有不同的类型date和2个全新类型geo和null
date: 与js的date类型兼容,但是可以使用服务器端生成大法, 也就是说在服务器端再生成date. 如: {createTime: db.serverDate()}
geo是地理位置, 看源文档吧
null是占位符, 表示字段存在但是没有值

查询和删除

默认从小程序增加一条记录都会有一个_id和_openid, 并且collection的默认读写权限限制在创建者也就是小程序用户本身的, 所以查询的时候即使不带_openid也只能查到自己的. 如果修改collection权限, 最多也只能扩展到读取所有记录, 而不能删改其他用户创建的记录.

增删改查代码对比

单条的增删改查(单条的查其实只能算是引用):

db.collection('todos').add({data: {description: "learn cloud database"})
db.collection('todos').doc(doc_id).remove()
db.collection('todos').doc(doc_id).update({data: {description: "learn cloud database"})
db.collection('todos').doc(doc_id).get()

多条的增删改查

增加多条只有服务端支持, 可使用云函数实现, 参考: https://blog.csdn.net/weixin_44702572/article/details/127438504
多条的改删查都是通过where来实现的, 并且用到_工具const _ = db.command

db.collection('todos').where({price: _.lt(100)}).get()
db.collection('todos').where({price: _.lt(100)}).remove()
db.collection('todos').where({price: _.lt(100)}).update({data: {description: "learn cloud database"})

对数组元素数量的修改:
前面省略.update({data: {tags: _.push('mini-program')}), 除了push还可以用popshiftunshift
对同一数据中数组元素单个值的修改: 假如有元素scores:[10, 20, 30]对单个数组元素值20改为25:
前面省略.update({data: {'scores.1': 25}})
对多组数据中数组元素单个值的修改. 第一个20改成25,前面有where,并且用$替代每一个找到的数据中第一个值的index
前面省略.where({scores: 20}).update({data: {'scores.$': 25}})
对同一数据的数组元素的所有值修改:
.update({data: {'scores.math.$[]': _.inc(10)}})

对象元素的修改, 只修改一个key的值:
前面省略.update({data: {style: {color: 'blue'}})
修改整个对象的值:
前面省略.update({data: {style: _.set({color: 'blue'})})
对对象的键值修改, 可以参考数组的点路径表示法, 如'root.objects.1.numbers.2': 80

分页

.skip(num)

统计

腾讯的文档写得不好, 不过这个数据库显然是nosql, 我估计可以参考mongodb的文档, 搜索后果不其然, 很多文章也说这个本质上就是mongodb.
统计主要是在collection上使用.aggregate(). 这个单词官方文档叫做"聚合", 实际上就有"统计"的含义.
这个和在excel里面做统计类似, 而且理论上应该会更强大.
.aggregate()以后使用一系列的操作处理数据, 最后得到想要的统计结果, 这一系列操作称之为"流水线"(mongodb中叫做管线pipeline), 而"操作"官方叫"聚合阶段".每一种操作都有其特定的一些工具(操作符), 为提高效率, 操作之间有优先顺序, 一些操作需要在另一些之前, 如: 可以缩减数据量的操作优先, 这样后面处理的操作数据量就会比较小.
对数据表中字段引用时, '$字段名'表示该字段标题, 用在_id里; $.操作符('$字段名')表示对字段下的数据按操作符要求操作. 还可用$.操作符(1)表示_id里引用的第1个字段.

聚合阶段 解释 操作符
group 像excel的数据透视表, _id是要透视的字段,可以多个,数据区是要统计的字段, 可以通过操作符设置统计方式. 这儿的操作符是所谓的"累计器", 即一个统计字段下的一组输入数据, 操作后变一个数据 addToSet(合为数组) mergeObjects(合并对象) avg first last max min push(合为数组且能定义数组元素) stdDevPop(标准差) stdDevSamp(样本标准差) sum
sort 排序 用法 .sort({字段名A: -1, 字段名B: 1}), -1为降序, 1为升序
sortByCount 是group+sort的操作 用法 .sortByCount('$字段名'), 只能以降序排列
match 用法同where 操作符同where, 不能使用聚合操作符
limit 结果数量,默认20, 可以修改 用法: .limit(数字)
skip 用于分页 用法: .skip(数字)
lookup 连表查询, 相当于excel的vlookup. 不同点是:1. excel只能匹配一个, 这儿会匹配出一组包括所有字段的数据并作为数组放在as的字段里; 2.本方字段为字符串,对方可以是字符串也可以是字符串数组 .lookup({from: '对方集合名',localField: '本方字段',foreignField: '对方字段',as: '结果数组字段'})
count 计算表中条目数,并映射到一个字段名输出 .count('字段名')
end 每个流水线最后都要带的, 指示执行 .end()
以下是不常用的
geoNear 按距离排序, 内容比较多, 因暂不涉及地图应用就不展开了
addFields 添加新字段, 比如对数组合计, 对几个字段运算得出新字段; 还可以用路径字符串给object添加子记录 可以用操作符
bucket 分组并进行运算.与group不同的是, bucket是通过边界来分组的,分组后_id为边界值 .bucket({groupBy: '$字段名',boundaries: [0, 50, 100], default: 'other', output: { count: $.sum(1),ids: $.push('$_id')}})
bucketAuto 与bucket区别是,bucketAuto通过指定分组数来尽量平均分组,并且自动输出每组最大值/最小值/计数而无须指定,分组依据也可以通过指定granularity来定规则 .bucketAuto({groupBy: '$字段名',buckets: 3})
project 映射字段, 其实就是给字段改个名字,也可以保留字段或删除字段,还可以用路径字符串嵌套 .project({保留字段名: 1, 删除字段名: 0, 全新字段名: 可包括操作符的对象})
replaceRoot 可以把对象字段提升一级, 把对象字段变成collection, 对象的属性变成字段, 也可以构建新的字段 .replaceRoot({newRoot: '$对象字段名'})
sample 随机抽样指定数量的记录 .simple(抽样数)
unwind 有点跟group相反, 将doc按一个数组字段拆分成多个doc .unwind('$数组字段名') 或 .unwind({path: '$数组字段名', includeArrayIndex: 'index', preserveNullAndEmptyArrays: true})

两种等价的操作形式

通过chatGPT和官方文档, 发现有两种等价的操作, 以group中提取日期中的年份为例:

// chatGPT的代码
db.collection('heightDataDebug').aggregate().group({
  _id: { $year: "$date" }
})
// 官方文档建议的代码
const $ = db.command.aggregate
db.collection('heightDataDebug').aggregate().group({
  _id: $.year('$date')
})

形式上来看, 官文突出了操作与数据的不同, 而chatGPT代码将操作作为key,数据作为value, 初看起来就有些迷惑. 但chatGPT这种形式可能说明了一个问题,就是这本质只是一个object而已,表述了运算的方式, 但没有进行运算. 实际运算是数据库端进行的.

云函数

服务端:

// index.js 是入口文件,云函数被调用时会执行该文件导出的 main 方法
// event 包含了调用端(小程序端)调用该函数时传过来的参数,同时还包含了可以通过 getWXContext 方法获取的用户登录态 `openId` 和小程序 `appId` 信息
const cloud = require('wx-server-sdk')
exports.main = async (event, context) => {
  let { userInfo, a, b} = event
  let { OPENID, APPID } = cloud.getWXContext() // 这里获取到的 openId 和 appId 是可信的
  let sum = a + b

  return {
    OPENID,
    APPID,
    sum
  }
}

客户端:

wx.cloud.callFunction({
  // 需调用的云函数名
  name: 'add',
  // 传给云函数的参数
  data: {
    a: 12,
    b: 19,
  },
  // 成功回调
  complete: console.log
})
// 当然 promise 方式也是支持的
wx.cloud.callFunction({
  name: 'add',
  data: {
    a: 12,
    b: 19
  }
}).then(console.log)

可以通过在data中传入type的方式, 使一个云函数支持多个子函数. 在服务端使用switch对type判断并调用子函数.

FAQ

  • console中提示: appservice.js:4786 当前基础库版本过低,建议调整最低支持基础库版本。 怎么调整?
    答: 百度搜到腾讯的官方文档是要求网页登录小程序后台,在设置-基本设置-版本设置-基础库最低可用版本中设置. 但是, 是不对的, 或者至少是不完整的.
    首先, 这行报错也没告诉你过低是低于多少, 现在是多少. 其次, 也没说在哪儿调整.
    其实这句报错查的是本地的基础库, 在小程序开发工具中点击右上角的详情-本地设置-调试基础库中修改. 版本一般建议改为最高的.
    但是究竟是比较了那个版本才说基础库过低呢?
    幸好appservice.js:4786是能跟踪到源码的, 源码压缩过,但格式化后还可以读懂. 可以看到下面这句:
    v = wx.getSystemInfoSync().SDKVersion,
    b = [];
    a.compareVersion(v, "2.10.3") >= 0 && b.push("wx://form-field-button"), a.compareVersion(v, "2.16.1") < 0 && console.warn("当前基础库版本过低,建议调整最低支持基础库版本。")

    所以, 通过wx.getSystemInfoSync().SDKVersion可以取到本地基础库, 最低要求是2.16.1.

隐私授权

小程序用户信息相关接口调整: https://developers.weixin.qq.com/community/develop/doc/000e881c7046a8fa1f4d464105b001?idescene=6

标签: none 阅读量: 577

添加新评论