小程序 | 云数据库的条件查询
1.1. 查询单条数据
我们先来看看如何获取一个记录的数据,假设我们已有一个_id
为todo-identifiant-aleatoire
的在集合todos
上的记录,那么我们可以通过在该记录的引用调用 get 方法获取这个待办事项的数据:
- db.collection('todos').doc('todo-identifiant-aleatoire').get({
- success: function(res) {
- // res.data 包含该记录的数据
- console.log(res.data)
- }
- })
也可以用 Promise 风格调用:
- db.collection('todos').doc('todo-identifiant-aleatoire')
- .get()
- .then(res => {
- // res.data 包含该记录的数据
- console.log(res.data)
- })
- .catch(err=>{
- console.log(err)
- })
1.2. 查询全部数据
在不指定_id
时,如果数据量不足 20 条,通过get()
可以查询全部数据。如果数据量超过 20 条,为了防止误操作以及保护小程序体验,小程序端在获取集合数据时服务器一次默认并且最多返回 20 条记录,云函数端这个数字则是 100。开发者可以通过 limit 方法指定需要获取的记录数量,但小程序端不能超过 20 条,云函数端不能超过 100 条。
- db.collection('todos').get({
- success: function(res) {
- // res.data 是一个包含集合中有权限访问的所有记录的数据,不超过 20 条
- console.log(res.data)
- }
- })
也可以用 Promise 风格调用:
- db.collection('todos').get().then(res => {
- // res.data 是一个包含集合中有权限访问的所有记录的数据,不超过 20 条
- console.log(res.data)
- })
下面是在云函数端获取一个集合所有记录的例子,因为有最多一次取 100 条的限制,因此很可能一个请求无法取出所有数据,需要分批次取:
- const cloud = require('wx-server-sdk')
- cloud.init()
-
- const db = cloud.database()
- const MAX_LIMIT = 100
-
- exports.main = async (event, context) => {
- // 先取出集合记录总数
- const countResult = await db.collection('todos').count()
- const total = countResult.total
- // 计算需分几次取
- const batchTimes = Math.ceil(total / 100)
- // 承载所有读操作的 promise 的数组
- const tasks = []
- for (let i = 0; i < batchTimes; i++) {
- const promise = db.collection('todos').skip(i * MAX_LIMIT).limit(MAX_LIMIT).get()
- tasks.push(promise)
- }
- // 等待所有
- return (await Promise.all(tasks)).reduce((acc, cur) => {
- return {
- data: acc.data.concat(cur.data),
- errMsg: acc.errMsg,
- }
- })
- }
1.3. 条件查询
1.3.1. where 和比较操作符
假设我们需要查询进度大于 30% 的待办事项,那么传入对象表示全等匹配的方式就无法满足了,这时就需要用到查询指令。数据库 API 提供了大于、小于等多种比较符(查询指令),这些指令都暴露在 db.command 对象上。比如查询进度大于 30% 的待办事项:
- const _ = db.command
- db.collection('todos').where({
- // gt 方法用于指定一个 "大于" 条件,此处 _.gt(30) 是一个 "大于 30" 的条件
- progress: _.gt(30)
- })
- .get({
- success: function(res) {
- console.log(res.data)
- }
- })
API 提供了以下比较操作符(查询指令):
查询指令 | 说明 |
---|---|
eq | 等于 |
neq | 不等于 |
lt | 小于 |
lte | 小于或等于 |
gt | 大于 |
gte | 大于或等于 |
in | 字段值在给定数组中 |
nin | 字段值不在给定数组中 |
更多具体的查询指令 API 文档可参考数据库 API 文档。
1.3.2. 逻辑指令(逻辑运算符)
除了指定一个字段满足一个条件之外,我们还可以通过指定一个字段需同时满足多个条件,比如用 and 逻辑指令查询进度在 30% 和 70% 之间的待办事项:
- const _ = db.command
- db.collection('todos').where({
- // and 方法用于指定一个 "与" 条件,此处表示需同时满足 _.gt(30) 和 _.lt(70) 两个条件
- progress: _.gt(30).and(_.lt(70))
- })
- .get({
- success: function(res) {
- console.log(res.data)
- }
- })
既然有 and,当然也有 or 了,比如查询进度为 0 或 100 的待办事项:
- const _ = db.command
- db.collection('todos').where({
- // or 方法用于指定一个 "或" 条件,此处表示需满足 _.eq(0) 或 _.eq(100)
- progress: _.eq(0).or(_.eq(100))
- })
- .get({
- success: function(res) {
- console.log(res.data)
- }
- })
如果我们需要跨字段进行 "或" 操作,可以做到吗?答案是肯定的,or 指令还可以用来接受多个(可以多于两个)查询条件,表示需满足多个查询条件中的任意一个,比如我们查询进度小于或等于 50% 或颜色为白色或黄色的待办事项:
- const _ = db.command
- db.collection('todos').where(_.or([
- {
- progress: _.lte(50)
- },
- {
- > color: _.in(['white', 'yellow'])
- }
- }
- ]))
- .get({
- success: function(res) {
- console.log(res.data)
- }
- })
更多具体的查询指令 API 文档可参考数据库 API 文档。