查询数据

在记录和集合上都有提供 get 方法用于获取单个记录或集合中多个记录的数据。

假设我们已有一个集合 todos,其中包含以下格式记录:

  1. [
  2. {
  3. _id: 'todo-identifiant-aleatoire',
  4. _openid: 'user-open-id', // 假设用户的 openid 为 user-open-id
  5. description: "learn cloud database",
  6. due: Date("2018-09-01"),
  7. progress: 20,
  8. tags: [
  9. "cloud",
  10. "database"
  11. ],
  12. style: {
  13. color: 'white',
  14. size: 'large'
  15. },
  16. location: Point(113.33, 23.33), // 113.33°E,23.33°N
  17. done: false
  18. },
  19. {
  20. _id: 'todo-identifiant-aleatoire-2',
  21. _openid: 'user-open-id', // 假设用户的 openid 为 user-open-id
  22. description: "write a novel",
  23. due: Date("2018-12-25"),
  24. progress: 50,
  25. tags: [
  26. "writing"
  27. ],
  28. style: {
  29. color: 'yellow',
  30. size: 'normal'
  31. },
  32. location: Point(113.22, 23.22), // 113.22°E,23.22°N
  33. done: false
  34. }
  35. // more...
  36. ]

获取一个记录的数据

我们先来看看如何获取一个记录的数据,假设我们已有一个 ID 为 todo-identifiant-aleatoire 的在集合 todos 上的记录,那么我们可以通过在该记录的引用调用 get 方法获取这个待办事项的数据:

  1. db.collection('todos').doc('todo-identifiant-aleatoire').get({
  2. success: function(res) {
  3. // res.data 包含该记录的数据
  4. console.log(res.data)
  5. }
  6. })

也可以用 Promise 风格调用:

  1. db.collection('todos').doc('todo-identifiant-aleatoire').get().then(res => {
  2. // res.data 包含该记录的数据
  3. console.log(res.data)
  4. })

获取多个记录的数据

我们也可以一次性获取多条记录。通过调用集合上的 where 方法可以指定查询条件,再调用 get 方法即可只返回满足指定查询条件的记录,比如获取用户的所有未完成的待办事项:

  1. db.collection('todos').where({
  2. _openid: 'user-open-id',
  3. done: false
  4. })
  5. .get({
  6. success: function(res) {
  7. // res.data 是包含以上定义的两条记录的数组
  8. console.log(res.data)
  9. }
  10. })

where 方法接收一个对象参数,该对象中每个字段和它的值构成一个需满足的匹配条件,各个字段间的关系是 “与” 的关系,即需同时满足这些匹配条件,在这个例子中,就是查询出 todos 集合中 _openid 等于 user-open-iddone 等于 false 的记录。在查询条件中我们也可以指定匹配一个嵌套字段的值,比如找出自己的标为黄色的待办事项:

  1. db.collection('todos').where({
  2. _openid: 'user-open-id',
  3. style: {
  4. color: 'yellow'
  5. }
  6. })
  7. .get({
  8. success: function(res) {
  9. console.log(res.data)
  10. }
  11. })

也可以用 “点表示法” 表示嵌套字段:

  1. db.collection('todos').where({
  2. _openid: 'user-open-id',
  3. 'style.color': 'yellow'
  4. })
  5. .get({
  6. success: function(res) {
  7. console.log(res.data)
  8. }
  9. })

获取一个集合的数据

如果要获取一个集合的数据,比如获取 todos 集合上的所有记录,可以在集合上调用 get 方法获取,但通常不建议这么使用,在小程序中我们需要尽量避免一次性获取过量的数据,只应获取必要的数据。为了防止误操作以及保护小程序体验,小程序端在获取集合数据时服务器一次默认并且最多返回 20 条记录,云函数端这个数字则是 100。开发者可以通过 limit 方法指定需要获取的记录数量,但小程序端不能超过 20 条,云函数端不能超过 100 条。

  1. db.collection('todos').get({
  2. success: function(res) {
  3. // res.data 是一个包含集合中有权限访问的所有记录的数据,不超过 20 条
  4. console.log(res.data)
  5. }
  6. })

也可以用 Promise 风格调用:

  1. db.collection('todos').get().then(res => {
  2. // res.data 是一个包含集合中有权限访问的所有记录的数据,不超过 20 条
  3. console.log(res.data)
  4. })

下面是在云函数端获取一个集合所有记录的例子,因为有最多一次取 100 条的限制,因此很可能一个请求无法取出所有数据,需要分批次取:

  1. const cloud = require('wx-server-sdk')
  2. cloud.init()
  3. const db = cloud.database()
  4. const MAX_LIMIT = 100
  5. exports.main = async (event, context) => {
  6. // 先取出集合记录总数
  7. const countResult = await db.collection('todos').count()
  8. const total = countResult.total
  9. // 计算需分几次取
  10. const batchTimes = Math.ceil(total / 100)
  11. // 承载所有读操作的 promise 的数组
  12. const tasks = []
  13. for (let i = 0; i < batchTimes; i++) {
  14. const promise = db.collection('todos').skip(i * MAX_LIMIT).limit(MAX_LIMIT).get()
  15. tasks.push(promise)
  16. }
  17. // 等待所有
  18. return (await Promise.all(tasks)).reduce((acc, cur) => {
  19. return {
  20. data: acc.data.concat(cur.data),
  21. errMsg: acc.errMsg,
  22. }
  23. })
  24. }