QQ小程序 增删改查
初始化
小程序端
在开始使用数据库 API 进行增删改查操作之前,需要先获取数据库的引用。以下调用获取默认环境的数据库的引用:
const db = qq.cloud.database()
如需获取其他环境的数据库引用,可以在调用时传入一个对象参数,在其中通过 env 字段指定要使用的环境。此时方法会返回一个对测试环境数据库的引用。 示例:假设有一个环境名为 test,用做测试环境,那么可以如下获取测试环境数据库:
如需获取其他环境的数据库引用,可以在调用时传入一个对象参数,在其中通过 env 字段指定要使用的环境。此时方法会返回一个对测试环境数据库的引用。 示例:假设有一个环境名为 test,用做测试环境,那么可以如下获取测试环境数据库:
const testDB = qq.cloud.database({
env: 'test'
})
要操作一个集合,需先获取它的引用。在获取了数据库的引用后,就可以通过数据库引用上的 collection 方法获取一个集合的引用了,比如获取待办事项清单集合:
const todos = db.collection('todos')
获取集合的引用并不会发起网络请求去拉取它的数据,我们可以通过此引用在该集合上进行增删查改的操作,除此之外,还可以通过集合上的 doc 方法来获取集合中一个指定 ID 的记录的引用。同理,记录的引用可以用于对特定记录进行更新和删除操作。 假设我们有一个待办事项的 ID 为 todo-identifiant-aleatoire,那么我们可以通过 doc 方法获取它的引用:
const todo = db.collection('todos').doc('todo-identifiant-aleatoire')
服务端:
示例代码如下:
const tcb = require("tcb-admin-node");
// 初始化资源
// 云函数下不需要secretId和secretKey。
// env如果不指定将使用默认环境
tcb.init({
secretId: 'xxxxx',
secretKey: 'xxxx',
env: 'xxx'
});
//云函数下使用默认环境
tcb.init();
//云函数下指定环境
tcb.init({
env: 'xxx'
});
插入数据
可以通过在集合对象上调用 add 方法往集合中插入一条记录。还是用待办事项清单的例子,比如我们想新增一个待办事项
小程序端
示例代码如下:
const db = qq.cloud.database();
db.collection('todos').add({
// data 字段表示需新增的 JSON 数据
data: {
// _id: 'todo-identifiant-aleatoire', // 可选自定义 _id,在此处场景下用数据库自动分配的就可以了
description: "learn cloud database",
due: new Date("2018-09-01"),
tags: [
"cloud",
"database"
],
// 为待办事项添加一个地理位置
location: new db.Geo.Point(23, 113),
done: false
},
})
.then(res => {
console.log(res)
})
.catch(console.error);
服务端
示例代码如下:
const app = require('tcb-admin-node');
app.init();
const db = app.database();
db.collection('todos').add({
// _id: 'todo-identifiant-aleatoire', // 可选自定义 _id,在此处场景下用数据库自动分配的就可以了
description: "learn cloud database",
due: new Date("2018-09-01"),
tags: [
"cloud",
"database"
],
// 为待办事项添加一个地理位置
location: new db.Geo.Point(23, 113),
done: false
})
.then(res => {
console.log(res)
})
.catch(console.error);
在创建成功之后,我们可以在控制台中查看到刚新增的数据。 可以在 add API 文档中查阅完整的 API 定义。
读取数据
在记录和集合上都有提供 get 方法用于获取单个记录或集合中多个记录的数据。 假设我们已有一个集合 todos,其中包含以下格式记录:
[
{
_id: 'todo-identifiant-aleatoire',
_openid: 'user-open-id', // 假设用户的 openid 为 user-open-id
description: "learn cloud database",
due: Date("2018-09-01"),
progress: 20,
tags: [
"cloud",
"database"
],
style: {
color: 'white',
size: 'large'
},
location: Point(113.33, 23.33), // 113.33°E,23.33°N
done: false
},
{
_id: 'todo-identifiant-aleatoire-2',
_openid: 'user-open-id', // 假设用户的 openid 为 user-open-id
description: "write a novel",
due: Date("2018-12-25"),
progress: 50,
tags: [
"writing"
],
style: {
color: 'yellow',
size: 'normal'
},
location: Point(113.22, 23.22), // 113.22°E,23.22°N
done: false
}
// more...
]
小程序端
获取一个记录的数据
我们先来看看如何获取一个记录的数据,假设我们已有一个 ID 为 todo-identifiant-aleatoire 的在集合 todos 上的记录,那么我们可以通过在该记录的引用调用 get 方法获取这个待办事项的数据:
db.collection('todos').doc('todo-identifiant-aleatoire').get().then(res => {
// res.data 包含该记录的数据
console.log(res.data)
})
获取多个记录的数据
我们也可以一次性获取多条记录。通过调用集合上的 where 方法可以指定查询条件,再调用 get 方法即可只返回满足指定查询条件的记录,获取用户的所有未完成的待办事项。示例代码如下:
db.collection('todos').where({
_openid: 'user-open-id',
done: false
})
.get().then((res) => {
// res.data 是包含以上定义的两条记录的数组
console.log(res.data);
});
where 方法接收一个对象参数,该对象中每个字段和它的值构成一个需满足的匹配条件,各个字段间的关系是 "与" 的关系,即需同时满足这些匹配条件,在这个例子中,就是查询出 todos 集合中 _openid 等于 user-open-id 且 done 等于 false 的记录。在查询条件中我们也可以指定匹配一个嵌套字段的值,找出自己的标为黄色的待办事项:
db.collection('todos').where({
\_openid: 'user-open-id',
style: {
color: 'yellow'
}
})
.get().then((res) => {
console.log(res.data);
});
使用 "点表示法" 表示嵌套字段:
db.collection('todos').where({
_openid: 'user-open-id',
'style.color': 'yellow'
})
.get().then((res) => {
console.log(res.data);
});
获取一个集合的数据
如果要获取一个集合的数据,获取 todos 集合上的所有记录,可以在集合上调用 get 方法获取,但通常不建议这么使用,在客户端中我们需要尽量避免一次性获取过量的数据,只应获取必要的数据。为了防止误操作以及保护用户体验,在获取集合数据时服务器一次最多返回 20 条记录。开发者可以通过 limit 方法指定需要获取的记录数量,但不能超过 20 条。
db.collection('todos').get().then((res) => {
// res.data 是一个包含集合中有权限访问的所有记录的数据,不超过 20 条
console.log(res.data);
});
服务端: 服务端的数据获取方法与客户端大致相同,请参考以下示例:
const app = require('tcb-admin-node');
app.init();
const db = app.database();
// 获取一个记录的数据
db.collection('todos').doc('todo-identifiant-aleatoire').get().then((res) => {
// res.data 包含该记录的数据
console.log(res.data);
});
// 获取多个记录的数据
db.collection('todos').where({
_openid: 'user-open-id',
done: false
})
.get().then((res) => {
// res.data 是包含以上定义的两条记录的数组
console.log(res.data);
});
// 获取一个集合的数据
db.collection('todos').get().then((res) => {
// res.data 是一个包含集合中有权限访问的所有记录的数据,不超过 20 条
console.log(res.data);
});
查询数据
使用数据库 API 提供的 where 方法我们可以构造复杂的查询条件完成复杂的查询任务。在本节中我们还是使用上一章节中使用的示例数据。
查询指令
假设我们需要查询进度大于 30% 的待办事项,那么传入对象表示全等匹配的方式就无法满足了,这时就需要用到查询指令。数据库 API 提供了大于、小于等多种查询指令,这些指令都暴露在 db.command 对象上。比如查询进度大于 30% 的待办事项:
const _ = db.command;
db.collection("todos")
.where({
// gt 方法用于指定一个 "大于" 条件,此处 _.gt(30) 是一个 "大于 30" 的条件
progress: _.gt(30)
})
.get()
.then(res => {
console.log(res.data);
});
API 提供了以下查询指令:
查询指令 | 说明 |
---|---|
eq | 等于 |
neq | 不等于 |
lt | 小于 |
lte | 小于或等于 |
gt | 大于 |
gte | 大于或等于 |
in | 字段值在给定数组中 |
nin | 字段值不在给定数组中 |
逻辑指令
除了指定一个字段满足一个条件之外,我们还可以通过指定一个字段需同时满足多个条件。 使用 and 逻辑指令查询进度在30%和70%之间的待办事项。示例如下:
const _ = db.command
db.collection('todos').where({
// and 方法用于指定一个 "与" 条件,此处表示需同时满足 _.gt(30) 和 _.lt(70) 两个条件
progress: _.gt(30).and(_.lt(70))
})
.get()
.then((res) => {
console.log(res.data);
});
使用 or 指令,查询进度为0或100的待办事项,示例如下:
const _ = db.command
db.collection('todos').where({
// or 方法用于指定一个 "或" 条件,此处表示需满足 _.eq(0) 或 _.eq(100)
progress: _.eq(0).or(_.eq(100))
})
.get().then((res) => {
console.log(res.data);
});
如需跨字段进行 "或" 操作,您也可以使用or指令,or指令同时可以用来接受多个(可以多于两个)查询条件,表示需满足多个查询条件中的任意一个。 查询进度小于或等于50%或颜色为白色或黄色的待办事项,示例如下:
const _ = db.command
db.collection('todos').where(_.or([
{
progress: _.lte(50)
},
{
style: {
color: _.in(['white', 'yellow'])
}
}
]))
.get()
.then((res) => {
console.log(res.data);
});
删除数据
在这章节我们一起看看如何使用数据库 API 完成数据删除,在本节中我们还是沿用读取数据章节中使用的数据。
小程序端
删除一条记录
对记录使用 remove 方法可以删除该条记录,示例代码如下
db.collection('todos').doc('todo-identifiant-aleatoire').remove().then((res) => {
console.log(res.data);
});
服务端
删除多条记录
如果需要更新多个数据,需在 Server 端进行操作(云函数)。可通过 where 语句选取多条记录执行删除,仅有权限删除的记录会被删除。例如删除所有已完成的待办事项。示例代码如下:
// 使用了 async await 语法
const app = require('tcb-admin-node');
app.init();
const db = app.database();
const _ = db.command;
exports.main = async (event, context) => {
try {
return await db.collection('todos').where({
done: true
}).remove();
} catch(e) {
console.error(e);
}
}
注意: 在大多数情况下,您只能操作自己的数据(自己的代表事项),不能操作其他人的数据(其他人的待办事项),如需操作他人数据需获取更高权限。