2.数据库操作
云开发提供的是文档类数据库,即所谓的“nosql”型数据库,类似MongoDB,由于我之前接触的全是关系型数据库,这也是我初次学习。
数据库操作,有两种形式,第一种,针对不敏感数据,可以直接使用微信小程序端提供的一套API;对于敏感数据,最好使用云开发端自己写云函数,由于云开发环境类似模拟的后台服务器,和前台微信小程序完全是独立的两个环境,所以更为安全。
- String:字符串
- Number:数字
- Object:对象
- Array:数组
- Bool:布尔值
- Date:时间
- Geo:多种地理位置类型
- Null
- 自定义安全规则
- 官方提供的四种简易权限配置:
所有用户可读,仅创建者可写
仅创建者可读写
所有用户可读
所有用户不可读写
- 初始化:
获取默认环境下的数据库:const db = wx.cloud.database()
获取指定环境下的:const dbTest = wx.cloud.database({env:'test'})
获取指定集合的引用:const todos = db.collection('todos')
获取指定集合内ID='balabala’的一条记录:const todo = db.collection('todos').doc('balabala')
- Insert 插入 .add()
回调风格(传入success/fail/complet)
db.collection('todos').add({
data:{...},
success:function(res){...}
})
Promise风格(不传入success…)
db.collection('todos').add({
data:{...}
}).then(res=>{...})
- select 查询 .get()
回调风格
db.collection('todos').doc('balabala').get({
success: function(res) {...}
})
Promise 风格
db.collection('todos').doc('balabala').get().then(res => {...})
- 逻辑指令 .where() .and() .and([,]) .or() .or([,])
gt=>大于,gte=>大于或等于,lt=>小于,lte=>小于或等于
eq=>等于,neq=>不等于,in=>包含,nin=>不包含
const _ = db.command
db.collection('').where(age : _.gt(30)).get(success: function(res){...})
db.collection('').where(age : _.gt(30).and(_.lt(60))).get(success: function(res){...})
db.collection('').where(_.or([{age : _.gt(30)},{gender:_.eq('女')}])).get(success: function(res){...})
- 更新 .update()
db.collection('').doc('balabala').update(data:{...},success: function(res){...})
- 其他操作
const _ = db.command
_.set() 设置 _.remove() 删除
_.inc() 原子自增字段值 _.mul() 原子自乘字段值
_.push() 数组字段尾部追加 _.pop() 数组字段尾部删除
_.shift() 数组字段头部删除 _.unshift() 数组字段头部增加
这些操作均是原子的,意味着并发写的安全性
const _ = db.command
db.collection('todos').doc('balabala').update({
data: {
progress: _.inc(10) //自增 10
},
success: function(res) {
console.log(res.data)
}
})
- 删除
const _ = db.command
db.collection('todos').doc('balabala').remove({
success: function(res) {
console.log(res.data)
}
})
删除多条数据,在server端操作:
//删除所有已完成的待办事项:
// 使用了 async await 语法
const cloud = require('wx-server-sdk')
const db = cloud.database()
const _ = db.command
exports.main = async (event, context) => {
try {
return await db.collection('todos').where({
done: true
}).remove()
} catch(e) {
console.error(e)
}
}
- 匹配-嵌套匹配
普通匹配
const _ = db.command
db.collection('user').where({
age:21,
gender:'男'
}).get(success: function(res){...})
嵌套匹配
const db = wx.cloud.database('test')
const _ = db.command
//1.传入形同的数据结构以匹配
db.collection('user').where({
likes:{
sport:'basketball',
color:'black'
}
}).get(success: function(res){...})
//2.“点表示法”
db.collection('user').where({
'likes.sport':'basketball',
'likes.color':'balck'
}).get(success: function(res){...})
数组匹配
const db = wx.cloud.database('test')
const _ = db.command
//1.匹配整个数组,传入整个数组
db.collection('user').where({
scores: [10, 20, 30]
}).get(success: function(res){...})
//2.匹配某个数组元素
db.collection('user').where({
scores: 20
}).get(success: function(res){...})
//3.匹配第n个元素
db.collection('user').doc('balabala').update({
data:{
'scores.1': 200
},
success: function(res){...}
})
//4.结合查询指令
db.collection('user').where({
scores: _.gt(0).and(_.lt(60))
}).get(success: function(res){...})
//5.数组中第一个符合查询条件的元素xxx.$
db.collection('user').where({
score: 30
}).update({
data:{
'scores.$': 300
},
success: function(res){...}
})
//6.数组中所有满足查询条件的元素xxx.$[]
{
"_id": "doc1",
"scores": {
"math": [10, 20, 30]
}
}
db.collection('todos').doc('doc1').update({
data: {
'scores.math.$[]': _.inc(10)
},
success: function(res){...}
})
//嵌套数组
{
"_id": "doc1",
"scores": {
"math": [
{ "examId": 1, "score": 10 },
{ "examId": 2, "score": 20 },
{ "examId": 3, "score": 30 }
]
}
}
db.collection('todos').doc('doc1').update({
data: {
'scores.math.$[].score': _.inc(10)
},
success: function(res){...}
})
//多重嵌套集合
{
"study": {
"math": [
{
"scores": [10, 20, 30]
},
{
"scores": [50, 60, 70]
}
]
}
}
db.collection('todos').where({
'study.math.1.scores.2': 700
}).get(success: function(res){...})
数据库-云开发HTTP API | 微信开放文档
const db = wx.cloud.database()
const watcher = db.collection('todos').where({
team: 'our dev team'
}).watch({
onChange: function(snapshot) {
console.log('docs\'s changed events', snapshot.docChanges)
console.log('query result snapshot after the event', snapshot.docs)
console.log('is init data', snapshot.type === 'init')
},
onError: function(err) {
console.error('the watch closed because of error', err)
}
})
// ...
// 等到需要关闭监听的时候调用 close() 方法
watcher.close()
云开发-Geo API
//求最好销量和最差销量的作者
const db = wx.cloud.database()
const $ = db.command.aggregate
const result = db.collection('books').aggregate()
.group({//第一阶段,按“类目+作者”分组
_id: {
category: '$category',
author: '$author',
},
totalSales: $.sum('$sales')
})
.sort({//第二阶段,排序
totalSales: -1,
})
.group({//第三阶段,得到结论
_id: '$_id.category',
bestSellingAuthor: $.first('$_id.author'),
bestSellingAuthorTotalSales: $.first('$totalSales'),
worstSellingAuthor: $.last('$_id.author'),
worstSellingAuthorTotalSales: $.last('$totalSales'),
})
.end().then(console.log)
可直接在控制台设置索引,
注意:
(1)字段顺序决定索引效果 (a,b 和 b,a
(2)字段排序决定排序查询是否可以命中索引
(3)添加唯一性限制的索引时,集合内不允许存在索引内字段完全形同或都是null的两条记录
JSON、CSV 文件必须是 UTF-8 的编码格式,且其内容类似 MongoDB 的导出格式