QQ小程序 增刪改查

2020-07-09 15:16 更新

初始化

小程序端

在開(kāi)始使用數(shù)據(jù)庫(kù) API 進(jìn)行增刪改查操作之前,需要先獲取數(shù)據(jù)庫(kù)的引用。以下調(diào)用獲取默認(rèn)環(huán)境的數(shù)據(jù)庫(kù)的引用:

  1. const db = qq.cloud.database()

如需獲取其他環(huán)境的數(shù)據(jù)庫(kù)引用,可以在調(diào)用時(shí)傳入一個(gè)對(duì)象參數(shù),在其中通過(guò) env 字段指定要使用的環(huán)境。此時(shí)方法會(huì)返回一個(gè)對(duì)測(cè)試環(huán)境數(shù)據(jù)庫(kù)的引用。 示例:假設(shè)有一個(gè)環(huán)境名為 test,用做測(cè)試環(huán)境,那么可以如下獲取測(cè)試環(huán)境數(shù)據(jù)庫(kù):

如需獲取其他環(huán)境的數(shù)據(jù)庫(kù)引用,可以在調(diào)用時(shí)傳入一個(gè)對(duì)象參數(shù),在其中通過(guò) env 字段指定要使用的環(huán)境。此時(shí)方法會(huì)返回一個(gè)對(duì)測(cè)試環(huán)境數(shù)據(jù)庫(kù)的引用。 示例:假設(shè)有一個(gè)環(huán)境名為 test,用做測(cè)試環(huán)境,那么可以如下獲取測(cè)試環(huán)境數(shù)據(jù)庫(kù):

  1. const testDB = qq.cloud.database({
  2. env: 'test'
  3. })

要操作一個(gè)集合,需先獲取它的引用。在獲取了數(shù)據(jù)庫(kù)的引用后,就可以通過(guò)數(shù)據(jù)庫(kù)引用上的 collection 方法獲取一個(gè)集合的引用了,比如獲取待辦事項(xiàng)清單集合:

  1. const todos = db.collection('todos')

獲取集合的引用并不會(huì)發(fā)起網(wǎng)絡(luò)請(qǐng)求去拉取它的數(shù)據(jù),我們可以通過(guò)此引用在該集合上進(jìn)行增刪查改的操作,除此之外,還可以通過(guò)集合上的 doc 方法來(lái)獲取集合中一個(gè)指定 ID 的記錄的引用。同理,記錄的引用可以用于對(duì)特定記錄進(jìn)行更新和刪除操作。 假設(shè)我們有一個(gè)待辦事項(xiàng)的 ID 為 todo-identifiant-aleatoire,那么我們可以通過(guò) doc 方法獲取它的引用:

  1. const todo = db.collection('todos').doc('todo-identifiant-aleatoire')

服務(wù)端:

示例代碼如下:

  1. const tcb = require("tcb-admin-node");
  2. // 初始化資源
  3. // 云函數(shù)下不需要secretId和secretKey。
  4. // env如果不指定將使用默認(rèn)環(huán)境
  5. tcb.init({
  6. secretId: 'xxxxx',
  7. secretKey: 'xxxx',
  8. env: 'xxx'
  9. });
  10. //云函數(shù)下使用默認(rèn)環(huán)境
  11. tcb.init();
  12. //云函數(shù)下指定環(huán)境
  13. tcb.init({
  14. env: 'xxx'
  15. });

插入數(shù)據(jù)

可以通過(guò)在集合對(duì)象上調(diào)用 add 方法往集合中插入一條記錄。還是用待辦事項(xiàng)清單的例子,比如我們想新增一個(gè)待辦事項(xiàng)

小程序端

示例代碼如下:

  1. const db = qq.cloud.database();
  2. db.collection('todos').add({
  3. // data 字段表示需新增的 JSON 數(shù)據(jù)
  4. data: {
  5. // _id: 'todo-identifiant-aleatoire', // 可選自定義 _id,在此處場(chǎng)景下用數(shù)據(jù)庫(kù)自動(dòng)分配的就可以了
  6. description: "learn cloud database",
  7. due: new Date("2018-09-01"),
  8. tags: [
  9. "cloud",
  10. "database"
  11. ],
  12. // 為待辦事項(xiàng)添加一個(gè)地理位置
  13. location: new db.Geo.Point(23, 113),
  14. done: false
  15. },
  16. })
  17. .then(res => {
  18. console.log(res)
  19. })
  20. .catch(console.error);

  1. 服務(wù)端
  2. 示例代碼如下:
  3. const app = require('tcb-admin-node');
  4. app.init();
  5. const db = app.database();
  6. db.collection('todos').add({
  7. // _id: 'todo-identifiant-aleatoire', // 可選自定義 _id,在此處場(chǎng)景下用數(shù)據(jù)庫(kù)自動(dòng)分配的就可以了
  8. description: "learn cloud database",
  9. due: new Date("2018-09-01"),
  10. tags: [
  11. "cloud",
  12. "database"
  13. ],
  14. // 為待辦事項(xiàng)添加一個(gè)地理位置
  15. location: new db.Geo.Point(23, 113),
  16. done: false
  17. })
  18. .then(res => {
  19. console.log(res)
  20. })
  21. .catch(console.error);

在創(chuàng)建成功之后,我們可以在控制臺(tái)中查看到剛新增的數(shù)據(jù)。 可以在 add API 文檔中查閱完整的 API 定義。

讀取數(shù)據(jù)

在記錄和集合上都有提供 get 方法用于獲取單個(gè)記錄或集合中多個(gè)記錄的數(shù)據(jù)。 假設(shè)我們已有一個(gè)集合 todos,其中包含以下格式記錄:

  1. [
  2. {
  3. _id: 'todo-identifiant-aleatoire',
  4. _openid: 'user-open-id', // 假設(shè)用戶的 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', // 假設(shè)用戶的 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. ]

小程序端

獲取一個(gè)記錄的數(shù)據(jù)

我們先來(lái)看看如何獲取一個(gè)記錄的數(shù)據(jù),假設(shè)我們已有一個(gè) ID 為 todo-identifiant-aleatoire 的在集合 todos 上的記錄,那么我們可以通過(guò)在該記錄的引用調(diào)用 get 方法獲取這個(gè)待辦事項(xiàng)的數(shù)據(jù):

  1. db.collection('todos').doc('todo-identifiant-aleatoire').get().then(res => {
  2. // res.data 包含該記錄的數(shù)據(jù)
  3. console.log(res.data)
  4. })

獲取多個(gè)記錄的數(shù)據(jù)

我們也可以一次性獲取多條記錄。通過(guò)調(diào)用集合上的 where 方法可以指定查詢條件,再調(diào)用 get 方法即可只返回滿足指定查詢條件的記錄,獲取用戶的所有未完成的待辦事項(xiàng)。示例代碼如下:

  1. db.collection('todos').where({
  2. _openid: 'user-open-id',
  3. done: false
  4. })
  5. .get().then((res) => {
  6. // res.data 是包含以上定義的兩條記錄的數(shù)組
  7. console.log(res.data);
  8. });

where 方法接收一個(gè)對(duì)象參數(shù),該對(duì)象中每個(gè)字段和它的值構(gòu)成一個(gè)需滿足的匹配條件,各個(gè)字段間的關(guān)系是 "與" 的關(guān)系,即需同時(shí)滿足這些匹配條件,在這個(gè)例子中,就是查詢出 todos 集合中 _openid 等于 user-open-id 且 done 等于 false 的記錄。在查詢條件中我們也可以指定匹配一個(gè)嵌套字段的值,找出自己的標(biāo)為黃色的待辦事項(xiàng):

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

使用 "點(diǎn)表示法" 表示嵌套字段:

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

獲取一個(gè)集合的數(shù)據(jù)

如果要獲取一個(gè)集合的數(shù)據(jù),獲取 todos 集合上的所有記錄,可以在集合上調(diào)用 get 方法獲取,但通常不建議這么使用,在客戶端中我們需要盡量避免一次性獲取過(guò)量的數(shù)據(jù),只應(yīng)獲取必要的數(shù)據(jù)。為了防止誤操作以及保護(hù)用戶體驗(yàn),在獲取集合數(shù)據(jù)時(shí)服務(wù)器一次最多返回 20 條記錄。開(kāi)發(fā)者可以通過(guò) limit 方法指定需要獲取的記錄數(shù)量,但不能超過(guò) 20 條。

  1. db.collection('todos').get().then((res) => {
  2. // res.data 是一個(gè)包含集合中有權(quán)限訪問(wèn)的所有記錄的數(shù)據(jù),不超過(guò) 20 條
  3. console.log(res.data);
  4. });

服務(wù)端: 服務(wù)端的數(shù)據(jù)獲取方法與客戶端大致相同,請(qǐng)參考以下示例:

  1. const app = require('tcb-admin-node');
  2. app.init();
  3. const db = app.database();
  4. // 獲取一個(gè)記錄的數(shù)據(jù)
  5. db.collection('todos').doc('todo-identifiant-aleatoire').get().then((res) => {
  6. // res.data 包含該記錄的數(shù)據(jù)
  7. console.log(res.data);
  8. });
  9. // 獲取多個(gè)記錄的數(shù)據(jù)
  10. db.collection('todos').where({
  11. _openid: 'user-open-id',
  12. done: false
  13. })
  14. .get().then((res) => {
  15. // res.data 是包含以上定義的兩條記錄的數(shù)組
  16. console.log(res.data);
  17. });
  18. // 獲取一個(gè)集合的數(shù)據(jù)
  19. db.collection('todos').get().then((res) => {
  20. // res.data 是一個(gè)包含集合中有權(quán)限訪問(wèn)的所有記錄的數(shù)據(jù),不超過(guò) 20 條
  21. console.log(res.data);
  22. });

查詢數(shù)據(jù)

使用數(shù)據(jù)庫(kù) API 提供的 where 方法我們可以構(gòu)造復(fù)雜的查詢條件完成復(fù)雜的查詢?nèi)蝿?wù)。在本節(jié)中我們還是使用上一章節(jié)中使用的示例數(shù)據(jù)。

查詢指令

假設(shè)我們需要查詢進(jìn)度大于 30% 的待辦事項(xiàng),那么傳入對(duì)象表示全等匹配的方式就無(wú)法滿足了,這時(shí)就需要用到查詢指令。數(shù)據(jù)庫(kù) API 提供了大于、小于等多種查詢指令,這些指令都暴露在 db.command 對(duì)象上。比如查詢進(jìn)度大于 30% 的待辦事項(xiàng):

  1. const _ = db.command;
  2. db.collection("todos")
  3. .where({
  4. // gt 方法用于指定一個(gè) "大于" 條件,此處 _.gt(30) 是一個(gè) "大于 30" 的條件
  5. progress: _.gt(30)
  6. })
  7. .get()
  8. .then(res => {
  9. console.log(res.data);
  10. });

API 提供了以下查詢指令:

查詢指令 說(shuō)明
eq 等于
neq 不等于
lt 小于
lte 小于或等于
gt 大于
gte 大于或等于
in 字段值在給定數(shù)組中
nin 字段值不在給定數(shù)組中

邏輯指令

除了指定一個(gè)字段滿足一個(gè)條件之外,我們還可以通過(guò)指定一個(gè)字段需同時(shí)滿足多個(gè)條件。 使用 and 邏輯指令查詢進(jìn)度在30%和70%之間的待辦事項(xiàng)。示例如下:

  1. const _ = db.command
  2. db.collection('todos').where({
  3. // and 方法用于指定一個(gè) "與" 條件,此處表示需同時(shí)滿足 _.gt(30) 和 _.lt(70) 兩個(gè)條件
  4. progress: _.gt(30).and(_.lt(70))
  5. })
  6. .get()
  7. .then((res) => {
  8. console.log(res.data);
  9. });

使用 or 指令,查詢進(jìn)度為0或100的待辦事項(xiàng),示例如下:

  1. const _ = db.command
  2. db.collection('todos').where({
  3. // or 方法用于指定一個(gè) "或" 條件,此處表示需滿足 _.eq(0)_.eq(100)
  4. progress: _.eq(0).or(_.eq(100))
  5. })
  6. .get().then((res) => {
  7. console.log(res.data);
  8. });

如需跨字段進(jìn)行 "或" 操作,您也可以使用or指令,or指令同時(shí)可以用來(lái)接受多個(gè)(可以多于兩個(gè))查詢條件,表示需滿足多個(gè)查詢條件中的任意一個(gè)。 查詢進(jìn)度小于或等于50%或顏色為白色或黃色的待辦事項(xiàng),示例如下:

  1. const _ = db.command
  2. db.collection('todos').where(_.or([
  3. {
  4. progress: _.lte(50)
  5. },
  6. {
  7. style: {
  8. color: _.in(['white', 'yellow'])
  9. }
  10. }
  11. ]))
  12. .get()
  13. .then((res) => {
  14. console.log(res.data);
  15. });

刪除數(shù)據(jù)

在這章節(jié)我們一起看看如何使用數(shù)據(jù)庫(kù) API 完成數(shù)據(jù)刪除,在本節(jié)中我們還是沿用讀取數(shù)據(jù)章節(jié)中使用的數(shù)據(jù)。

小程序端

刪除一條記錄

  1. 對(duì)記錄使用 remove 方法可以刪除該條記錄,示例代碼如下
  2. db.collection('todos').doc('todo-identifiant-aleatoire').remove().then((res) => {
  3. console.log(res.data);
  4. });

服務(wù)端

刪除多條記錄

如果需要更新多個(gè)數(shù)據(jù),需在 Server 端進(jìn)行操作(云函數(shù))??赏ㄟ^(guò) where 語(yǔ)句選取多條記錄執(zhí)行刪除,僅有權(quán)限刪除的記錄會(huì)被刪除。例如刪除所有已完成的待辦事項(xiàng)。示例代碼如下:

  1. // 使用了 async await 語(yǔ)法
  2. const app = require('tcb-admin-node');
  3. app.init();
  4. const db = app.database();
  5. const _ = db.command;
  6. exports.main = async (event, context) => {
  7. try {
  8. return await db.collection('todos').where({
  9. done: true
  10. }).remove();
  11. } catch(e) {
  12. console.error(e);
  13. }
  14. }

注意: 在大多數(shù)情況下,您只能操作自己的數(shù)據(jù)(自己的代表事項(xiàng)),不能操作其他人的數(shù)據(jù)(其他人的待辦事項(xiàng)),如需操作他人數(shù)據(jù)需獲取更高權(quán)限。

以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)