日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
創(chuàng)新互聯(lián)小程序教程:微信小程序云開發(fā)數(shù)據(jù)庫

如在云開發(fā)數(shù)據(jù)庫的基礎介紹中所說,云開發(fā)提供了一個 JSON 數(shù)據(jù)庫,本章將介紹以下內(nèi)容:

  • 上手:用控制臺創(chuàng)建我的第一個集合,插入我的第一條數(shù)據(jù)
  • 數(shù)據(jù)類型:了解數(shù)據(jù)庫提供的數(shù)據(jù)類型
  • 權(quán)限控制:控制集合與記錄的讀寫權(quán)限
  • 初始化:初始化數(shù)據(jù)庫 API
  • 插入數(shù)據(jù)
  • 讀取數(shù)據(jù):讀取數(shù)據(jù)
  • 構(gòu)建查詢條件:構(gòu)建簡單或復雜的查詢條件
  • 更新數(shù)據(jù):數(shù)據(jù)的局部更新與替換更新
  • 刪除數(shù)據(jù)
  • 索引管理:為字段添加索引實現(xiàn)高效讀寫

另外可參考小程序端和云函數(shù)端的數(shù)據(jù)庫 API 文檔


上手云數(shù)據(jù)庫

這一節(jié)我們將介紹如何在控制臺中創(chuàng)建我們的第一個數(shù)據(jù)庫集合、往集合上插入數(shù)據(jù)、以及在控制臺中查看剛剛插入的數(shù)據(jù)。

創(chuàng)建第一個集合

打開控制臺,選擇 "數(shù)據(jù)庫" 標簽頁,通過 "添加集合" 入口創(chuàng)建一個集合。假設我們要創(chuàng)建一個待辦事項小程序,我們創(chuàng)建一個名為 todos 的集合。創(chuàng)建成功后,可以看到 todos 集合管理界面,界面中我們可以添加記錄、查找記錄、管理索引和管理權(quán)限。

創(chuàng)建第一條記錄

控制臺提供了可視化添加數(shù)據(jù)的交互界面,點擊 "添加記錄" 添加我們的第一條待辦事項:

{
  // 描述,String 類型
  "description": "learn mini-program cloud service",
  // 截止時間,Date 類型
  "due": Date("2018-09-01"),
  // 標簽,Array 類型
  "tags": [
    "tech",
    "mini-program",
    "cloud"
  ],
  // 個性化樣式,Object 類型
  "style": {
    "color": "red"
  },
  // 是否已完成,Boolean 類型
  "done": false
}

添加完成后可在控制臺中查看到剛添加的數(shù)據(jù)。

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

云控制臺支持上傳文件導入已有的數(shù)據(jù),可查看導入指引了解如何操作。

接下來,我們一起了解下數(shù)據(jù)庫都提供了哪些數(shù)據(jù)類型。


數(shù)據(jù)類型

云開發(fā)數(shù)據(jù)庫提供以下幾種數(shù)據(jù)類型:

  • String:字符串
  • Number:數(shù)字
  • Object:對象
  • Array:數(shù)組
  • Bool:布爾值
  • GeoPoint:地理位置點
  • Date:時間
  • Null

下面對幾個需要額外說明的字段做下補充說明。

Date

Date 類型用于表示時間,精確到毫秒,在小程序端可用 JavaScript 內(nèi)置 Date 對象創(chuàng)建。需要特別注意的是,在小程序端創(chuàng)建的時間是客戶端時間,不是服務端時間,這意味著在小程序端的時間與服務端時間不一定吻合,如果需要使用服務端時間,應該用 API 中提供的 serverDate 對象來創(chuàng)建一個服務端當前時間的標記,當使用了 serverDate 對象的請求抵達服務端處理時,該字段會被轉(zhuǎn)換成服務端當前的時間,更棒的是,我們在構(gòu)造 serverDate 對象時還可通過傳入一個有 offset 字段的對象來標記一個與當前服務端時間偏移 offset 毫秒的時間,這樣我們就可以達到比如如下效果:指定一個字段為服務端時間往后一個小時。

那么當我們需要使用客戶端時間時,存放 Date 對象和存放毫秒數(shù)是否是一樣的效果呢?不是的,我們的數(shù)據(jù)庫有針對日期類型的優(yōu)化,建議大家使用時都用 Date 或 serverDate 構(gòu)造時間對象。

GeoPoint

GeoPoint 類型用于表示地理位置點,用經(jīng)緯度唯一標記一個點,這是一個特殊的數(shù)據(jù)存儲類型。注意,如果需要對類型為地理位置的字段進行查找,一定要建立地理位置索引。

具體的地理位置 API 可參考 Geo API 文檔

Null

null 相當于一個占位符,表示一個字段存在但是值為空。


權(quán)限控制

數(shù)據(jù)庫的權(quán)限分為小程序端和管理端,管理端包括云函數(shù)端和控制臺。小程序端運行在小程序中,讀寫數(shù)據(jù)庫受權(quán)限控制限制,管理端運行在云函數(shù)上,擁有所有讀寫數(shù)據(jù)庫的權(quán)限。云控制臺的權(quán)限同管理端,擁有所有權(quán)限。小程序端操作數(shù)據(jù)庫應有嚴格的安全規(guī)則限制。

初期我們對操作數(shù)據(jù)庫開放以下幾種權(quán)限配置,每個集合可以擁有一種權(quán)限配置,權(quán)限配置的規(guī)則是作用在集合的每個記錄上的。出于易用性和安全性的考慮,云開發(fā)為云數(shù)據(jù)庫做了小程序深度整合,在小程序中創(chuàng)建的每個數(shù)據(jù)庫記錄都會帶有該記錄創(chuàng)建者(即小程序用戶)的信息,以 _openid 字段保存用戶的 openid 在每個相應用戶創(chuàng)建的記錄中。因此,權(quán)限控制也相應圍繞著一個用戶是否應該擁有權(quán)限操作其他用戶創(chuàng)建的數(shù)據(jù)展開。

以下按照權(quán)限級別從寬到緊排列如下:

  • 僅創(chuàng)建者可寫,所有人可讀:數(shù)據(jù)只有創(chuàng)建者可寫、所有人可讀;比如文章。
  • 僅創(chuàng)建者可讀寫:數(shù)據(jù)只有創(chuàng)建者可讀寫,其他用戶不可讀寫;比如用私密相冊。
  • 僅管理端可寫,所有人可讀:該數(shù)據(jù)只有管理端可寫,所有人可讀;如商品信息。
  • 僅管理端可讀寫:該數(shù)據(jù)只有管理端可讀寫;如后臺用的不暴露的數(shù)據(jù)。

簡而言之,管理端始終擁有讀寫所有數(shù)據(jù)的權(quán)限,小程序端始終不能寫他人創(chuàng)建的數(shù)據(jù),小程序端的記錄的讀寫權(quán)限其實分為了 “所有人可讀,只有創(chuàng)建者可寫“、”僅創(chuàng)建者可讀寫“、”所有人可讀,僅管理端可寫“、”所有人不可讀,僅管理端可讀寫“。

對一個用戶來說,不同模式在小程序端和管理端的權(quán)限表現(xiàn)如下:

模式 小程序端
讀自己創(chuàng)建的數(shù)據(jù)
小程序端
寫自己創(chuàng)建的數(shù)據(jù)
小程序端
讀他人創(chuàng)建的數(shù)據(jù)
小程序端
寫他人創(chuàng)建的數(shù)據(jù)
管理端
讀寫任意數(shù)據(jù)
僅創(chuàng)建者可寫,所有人可讀 ×
僅創(chuàng)建者可讀寫 × ×
僅管理端可寫,所有人可讀 × ×
僅管理端可讀寫:該數(shù)據(jù)只有管理端可讀寫 × × × ×

在設置集合權(quán)限時應謹慎設置,防止出現(xiàn)越權(quán)操作。


初始化

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

const db = wx.cloud.database()

如需獲取其他環(huán)境的數(shù)據(jù)庫引用,可以在調(diào)用時傳入一個對象參數(shù),在其中通過 env 字段指定要使用的環(huán)境。此時方法會返回一個對測試環(huán)境數(shù)據(jù)庫的引用。

示例:假設有一個環(huán)境名為 test,用做測試環(huán)境,那么可以如下獲取測試環(huán)境數(shù)據(jù)庫:

const testDB = wx.cloud.database({
  env: 'test'
})

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

const todos = db.collection('todos')

獲取集合的引用并不會發(fā)起網(wǎng)絡請求取拉取它的數(shù)據(jù),我們可以通過此引用在該集合上進行增刪查改的操作,除此之外,還可以通過集合上的 doc 方法來獲取集合中一個指定 ID 的記錄的引用。同理,記錄的引用可以用于對特定記錄進行更新和刪除操作。

假設我們有一個待辦事項的 ID 為 todo-identifiant-aleatoire,那么我們可以通過 doc 方法獲取它的引用:

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

接下來,我們看看如何往集合中插入數(shù)據(jù)。


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

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

db.collection('todos').add({
  // data 字段表示需新增的 JSON 數(shù)據(jù)
  data: {
    // _id: 'todo-identifiant-aleatoire', // 可選自定義 _id,在此處場景下用數(shù)據(jù)庫自動分配的就可以了
    description: "learn cloud database",
    due: new Date("2018-09-01"),
    tags: [
      "cloud",
      "database"
    ],
    // 為待辦事項添加一個地理位置(113°E,23°N)
    location: new db.Geo.Point(113, 23),
    done: false
  },
  success: function(res) {
    // res 是一個對象,其中有 _id 字段標記剛創(chuàng)建的記錄的 id
    console.log(res)
  }
})

當然,Promise 風格也是支持的,只要傳入對象中沒有 success, fail 或 complete,那么 add 方法就會返回一個 Promise:

db.collection('todos').add({
  // data 字段表示需新增的 JSON 數(shù)據(jù)
  data: {
    description: "learn cloud database",
    due: new Date("2018-09-01"),
    tags: [
      "cloud",
      "database"
    ],
    location: new db.Geo.Point(113, 23),
    done: false
  }
})
.then(res => {
  console.log(res)
})

數(shù)據(jù)庫的增刪查改 API 都同時支持回調(diào)風格和 Promise 風格調(diào)用。

在創(chuàng)建成功之后,我們可以在控制臺中查看到剛新增的數(shù)據(jù)。

可以在 add API 文檔中查閱完整的 API 定義。

接下來,我們將學習如何使用 API 查詢到剛插入的數(shù)據(jù)。


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

在記錄和集合上都有提供 get 方法用于獲取單個記錄或集合中多個記錄的數(shù)據(jù)。

假設我們已有一個集合 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...
]

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

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

db.collection('todos').doc('todo-identifiant-aleatoire').get({
  success: function(res) {
    // res.data 包含該記錄的數(shù)據(jù)
    console.log(res.data)
  }
})

也可以用 Promise 風格調(diào)用:

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

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

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

db.collection('todos').where({
  _openid: 'user-open-id',
  done: false
})
.get({
  success: function(res) {
    // res.data 是包含以上定義的兩條記錄的數(shù)組
    console.log(res.data)
  }
})

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

db.collection('todos').where({
  _openid: 'user-open-id',
  style: {
    color: 'yellow'
  }
})
.get({
  success: function(res) {
    console.log(res.data)
  }
})

也可以用 "點表示法" 表示嵌套字段:

db.collection('todos').where({
  _openid: 'user-open-id',
  'style.color': 'yellow'
})
.get({
  success: function(res) {
    console.log(res.data)
  }
})

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

如果要獲取一個集合的數(shù)據(jù),比如獲取 todos 集合上的所有記錄,可以在集合上調(diào)用 get 方法獲取,但通常不建議這么使用,在小程序中我們需要盡量避免一次性獲取過量的數(shù)據(jù),只應獲取必要的數(shù)據(jù)。為了防止誤操作以及保護小程序體驗,小程序端在獲取集合數(shù)據(jù)時服務器一次默認并且最多返回 20 條記錄,云函數(shù)端這個數(shù)字則是 100。開發(fā)者可以通過 limit 方法指定需要獲取的記錄數(shù)量,但小程序端不能超過 20 條,云函數(shù)端不能超過 100 條。

db.collection('todos').get({
  success: function(res) {
    // res.data 是一個包含集合中有權(quán)限訪問的所有記錄的數(shù)據(jù),不超過 20 條
    console.log(res.data)
  }
})

也可以用 Promise 風格調(diào)用:

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

下面是在云函數(shù)端獲取一個集合所有記錄的例子,因為有最多一次取 100 條的限制,因此很可能一個請求無法取出所有數(shù)據(jù),需要分批次?。?/p>

const cloud = require('wx-server-sdk')
cloud.init()
const db = cloud.database()
const MAX_LIMIT = 100
exports.main = async (event, context) => {
  // 先取出集合記錄總數(shù)
  const countResult = await db.collection('todos').count()
  const total = countResult.total
  // 計算需分幾次取
  const batchTimes = Math.ceil(total / 100)
  // 承載所有讀操作的 promise 的數(shù)組
  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,
    }
  })
}

接下來,我們將學習如何使用進階的查詢條件來完成簡單或復雜的查詢。


構(gòu)建查詢條件

使用數(shù)據(jù)庫 API 提供的 where 方法我們可以構(gòu)造復雜的查詢條件完成復雜的查詢?nèi)蝿铡?/p>

查詢指令

假設我們需要查詢進度大于 30% 的待辦事項,那么傳入對象表示全等匹配的方式就無法滿足了,這時就需要用到查詢指令。數(shù)據(jù)庫 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 字段值在給定數(shù)組中
nin 字段值不在給定數(shù)組中

具體的查詢指令 API 文檔可參考數(shù)據(jù)庫 API 文檔。

邏輯指令

除了指定一個字段滿足一個條件之外,我們還可以通過指定一個字段需同時滿足多個條件,比如用 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)
  },
  {
    style: {
      color: _.in(['white', 'yellow'])
    }
  }
]))
.get({
  success: function(res) {
    console.log(res.data)
  }
})

具體的邏輯查詢指令 API 文檔可參考數(shù)據(jù)庫 API 文檔。

接下來,我們一起學習如何更新數(shù)據(jù)。


更新數(shù)據(jù)

現(xiàn)在我們一起看看如何使用數(shù)據(jù)庫 API 完成數(shù)據(jù)更新。

更新數(shù)據(jù)主要有兩個方法:

API 說明
update 局部更新一個或多個記錄
set 替換更新一個記錄

局部更新

使用 update 方法可以局部更新一個記錄或一個集合中的記錄,局部更新意味著只有指定的字段會得到更新,其他字段不受影響。

比如我們可以用以下代碼將一個待辦事項置為已完成:

db.collection('todos').doc('todo-identifiant-aleatoire').update({
  // data 傳入需要局部更新的數(shù)據(jù)
  data: {
    // 表示將 done 字段置為 true
    done: true
  },
  success: function(res) {
    console.log(res.data)
  }
})

除了用指定值更新字段外,數(shù)據(jù)庫 API 還提供了一系列的更新指令用于執(zhí)行更復雜的更新操作,更新指令可以通過 db.command 取得:

更新指令 說明
set 設置字段為指定值
remove 刪除字段
inc 原子自增字段值
mul 原子自乘字段值
push 如字段值為數(shù)組,往數(shù)組尾部增加指定值
pop 如字段值為數(shù)組,從數(shù)組尾部刪除一個元素
shift 如字段值為數(shù)組,從數(shù)組頭部刪除一個元素
unshift 如字段值為數(shù)組,往數(shù)組頭部增加指定值

比如我們可以將一個待辦事項的進度 +10%:

const _ = db.command
db.collection('todos').doc('todo-identifiant-aleatoire').update({
  data: {
    // 表示指示數(shù)據(jù)庫將字段自增 10
    progress: _.inc(10)
  },
  success: function(res) {
    console.log(res.data)
  }
})

用 inc 指令而不是取出值、加 10 再寫進去的好處在于這個寫操作是個原子操作,不會受到并發(fā)寫的影響,比如同時有兩名用戶 A 和 B 取了同一個字段值,然后分別加上 10 和 20 再寫進數(shù)據(jù)庫,那么這個字段最終結(jié)果會是加了 20 而不是 30。如果使用 inc 指令則不會有這個問題。

如果字段是個數(shù)組,那么我們可以使用 push、pop、shift 和 unshift 對數(shù)組進行原子更新操作,比如給一條待辦事項加多一個標簽:

const _ = db.command
db.collection('todos').doc('todo-identifiant-aleatoire').update({
  data: {
    tags: _.push('mini-program')
  },
  success: function(res) {
    console.log(res.data)
  }
})

可能讀者已經(jīng)注意到我們提供了 set 指令,這個指令有什么用呢?這個指令的用處在于更新一個字段值為另一個對象。比如如下語句是更新 style.color 字段為 'blue' 而不是把 style 字段更新為 { color: 'blue' } 對象:

const _ = db.command
db.collection('todos').doc('todo-identifiant-aleatoire').update({
  data: {
    style: {
      color: 'blue'
    }
  },
  success: function(res) {
    console.log(res.data)
  }
})

如果需要將這個 style 字段更新為另一個對象,可以使用 set 指令:

const _ = db.command
db.collection('todos').doc('todo-identifiant-aleatoire').update({
  data: {
    style: _.set({
      color: 'blue'
    })
  },
  success: function(res) {
    console.log(res.data)
  }
})

如果需要更新多個數(shù)據(jù),需在 Server 端進行操作(云函數(shù)),在 where 語句后同樣的調(diào)用 update 方法即可,比如將所有未完待辦事項的進度加 10%:

// 使用了 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: false  
    })
    .update({
      data: {
        progress: _.inc(10)
      },
    })
  } catch(e) {
    console.error(e)
  }
}

更完整詳細的更新指令可以參考數(shù)據(jù)庫 API 文檔

替換更新

如果需要替換更新一條記錄,可以在記錄上使用 set 方法,替換更新意味著用傳入的對象替換指定的記錄:

const _ = db.command
db.collection('todos').doc('todo-identifiant-aleatoire').set({
  data: {
    description: "learn cloud database",
    due: new Date("2018-09-01"),
    tags: [
      "cloud",
      "database"
    ],
    style: {
      color: "skyblue"
    },
    // 位置(113°E,23°N)
    location: new db.Geo.Point(113, 23),
    done: false
  },
  success: function(res) {
    console.log(res.data)
  }
})

如果指定 ID 的記錄不存在,則會自動創(chuàng)建該記錄,該記錄將擁有指定的 ID。

接下來,我們將一起學習如何刪除記錄。


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

我們一起看看如何使用數(shù)據(jù)庫 API 完成數(shù)據(jù)刪除。

刪除一條記錄

對記錄使用 remove 方法可以刪除該條記錄,比如:

db.collection('todos').doc('todo-identifiant-aleatoire').remove({
  success: function(res) {
    console.log(res.data)
  }
})

刪除多條記錄

如果需要更新多個數(shù)據(jù),需在 Server 端進行操作(云函數(shù))??赏ㄟ^ where 語句選取多條記錄執(zhí)行刪除,只有有權(quán)限刪除的記錄會被刪除。比如刪除所有已完成的待辦事項:

// 使用了 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)
  }
}

在大多數(shù)情況下,我們希望用戶只能操作自己的數(shù)據(jù)(自己的代表事項),不能操作其他人的數(shù)據(jù)(其他人的待辦事項),這就需要引入權(quán)限控制了。

接下來,我們看看如何控制集合與記錄的讀寫權(quán)限,達到保護數(shù)據(jù)的目的。


索引管理

建立索引是保證數(shù)據(jù)庫性能、保證小程序體驗的重要手段。我們應為所有需要成為查詢條件的字段建立索引。建立索引的入口在控制臺中,可分別對各個集合的字段添加索引。

單字段索引

對需要作為查詢條件篩選的字段,我們可以創(chuàng)建單字段索引。如果需要對嵌套字段進行索引,那么可以通過 "點表示法" 用點連接起嵌套字段的名稱。比如我們需要對如下格式的記錄中的 color 字段進行索引時,可以用 style.color 表示。

{
  _id: '',
  style: {
    color: ''
  }
}

在設置單字段索引時,指定排序為升序或降序并沒有關(guān)系。在需要對索引字段按排序查詢時,數(shù)據(jù)庫能夠正確的對字段排序,無論索引設置為升序還是降序。

組合索引

組合索引即一個索引包含多個字段。當查詢條件使用的字段包含在索引定義的所有字段或前綴字段里時,會命中索引,優(yōu)化查詢性能。索引前綴即組合索引的字段中定義的前 1 到多個字段,如有在 A, B, C 三個字段定義的組合索引 A, B, C,那么 A 和 A, B 都屬于該索引的前綴。

組合索引具有以下特點:

1. 字段順序決定索引效果

定義組合索引時,多個字段間的順序不同是會有不同的索引效果的。比如對兩個字段 A 和 B 進行索引,定義組合索引為 A, B 與定義組合索引為 B, A是不同的。當定義組合索引為 A, B 時,索引會先按 A 字段排序再按 B 字段排序。因此當組合索引設為 A, B 時,即使我們沒有單獨對字段 A 設立索引,但對字段 A 的查詢可以命中 A, B 索引。需要注意的是,此時對字段 B 的查詢是無法命中 A, B 索引的,因為 B 不屬于索引 A, B 的前綴之一。

2. 字段排序決定排序查詢是否可以命中索引

加入我們對字段 A 和 B 設置以下索引:

A: 升序
B: 降序

那么當我們查詢需要對 A, B 進行排序時,可以指定排序結(jié)果為 A 升序 B 降序或 A 降序 B 升序,但不能指定為 A 升序 B 升序或 A 降序 B 降序。


索引屬性

唯一性限制

創(chuàng)建索引時可以指定增加唯一性限制,具有唯一性限制的索引會要求被索引集合不能存在被索引字段值都相同的兩個記錄。即對任意具有唯一性限制的索引 I,假設其索引字段為 ,則對集合 S 中任意的兩個記錄 R1 和 R2,必須滿足條件 R1.F1 != R2.F1 && R1.F2 != R2.F2 && ... && R1.Fn != R2.Fn。需特別注意的是,假如記錄中不存在某個字段,則對索引字段來說其值默認為 null,如果索引有唯一性限制,則不允許存在兩個或以上的該字段為空 / 不存在該字段的記錄。

在創(chuàng)建索引的時候索引屬性選擇 唯一 即可添加唯一性限制。


數(shù)據(jù)庫導入

云開發(fā)控制臺支持從文件導入已有的數(shù)據(jù)。目前僅支持導入 CSV、JSON 格式的文件數(shù)據(jù)。

要導入數(shù)據(jù),需打開云開發(fā)控制臺,切換到 “數(shù)據(jù)庫” 標簽頁,并選擇要導入數(shù)據(jù)的集合,點擊 “導入” 按鈕。

選擇要導入的 CSV 或者 JSON 文件,以及沖突處理模式,點擊 “導入” 按鈕即可開始導入。

文件格式

JSON、CSV 文件必須是 UTF-8 的編碼格式,且其內(nèi)容類似 MongoDB 的導出格式,例如:

JSON:

{
    "_id": "xxxxxx",
    "age": 45
}
{
    "_id": "yyyyyy",
    "age": 21
}

CSV:

_id,age
xxxxxx,45
yyyyyy,21

需要注意以下幾點:

1、JSON 數(shù)據(jù)不是數(shù)組,而是類似 JSON Lines,即各個記錄對象之間使用 \n 分隔,而非逗號;

2、JSON 數(shù)據(jù)每個鍵值對的鍵名首尾不能是 .,例如 ".a"、"abc.",且不能包含多個連續(xù)的 .,例如 "a..b";

3、鍵名不能重復,且不能有歧義,例如 {"a": 1, "a": 2} 或 {"a": {"b": 1}, "a.b": 2};

4、時間格式須為 ISODate 格式,例如 "date": { "$date" : "2018-08-31T17:30:00.882Z" };

5、當使用 Insert 沖突處理模式時,同一文件不能存在重復的 _id 字段,或與數(shù)據(jù)庫已有記錄相同的 _id 字段;

6、CSV 格式的數(shù)據(jù)默認以第一行作為導入后的所有鍵名,余下的每一行則是與首行鍵名一一對應的鍵值記錄。

目前提供了 Insert、Upsert 兩種沖突處理模式。Insert 模式會在導入時總是插入新記錄,Upsert 則會判斷有無該條記錄,如果有則更新記錄,否則就插入一條新記錄。

導入完成后,可以在提示信息中看到本次導入記錄的情況。


數(shù)據(jù)庫導出

云開發(fā)控制臺支持導出集合已有的數(shù)據(jù)。目前僅支持導出 CSV、JSON 格式的文件數(shù)據(jù)。

要導出數(shù)據(jù),需打開云開發(fā)控制臺,切換到 “數(shù)據(jù)庫” 標簽頁,并選擇要導出數(shù)據(jù)的集合,點擊 “導出” 鏈接。

選擇要導出的格式、保存的位置,以及字段,點擊 “導出” 按鈕即可開始導出的過程。

當選擇導出格式為 JSON 時,若不填寫字段項,則默認導出所有數(shù)據(jù)。

當選擇導出格式為 CSV 時,則字段為必填項。字段之間使用英文逗號隔開,例如:

_id,name,age,gender

數(shù)據(jù)庫備份與回檔

從開發(fā)者工具 1.02.202002282 版本開始,云開發(fā)提供了數(shù)據(jù)庫回檔功能。系統(tǒng)會自動開啟數(shù)據(jù)庫備份,并于每日凌晨自動進行一次數(shù)據(jù)備份,最長保存 7 天的備份數(shù)據(jù)。如有需要,開發(fā)者可在云控制臺上通過新建回檔任務將集合回檔(還原)至指定時間點。

回檔期間,數(shù)據(jù)庫的數(shù)據(jù)訪問不受影響?;貦n完成后,開發(fā)者可在集合列表中看到原有數(shù)據(jù)庫集合和回檔后的集合。

新建回檔

  1. 登錄微信開發(fā)者工具的云開發(fā)控制臺。
  2. 在數(shù)據(jù)庫頁面點擊數(shù)據(jù)庫回檔后可新建回檔任務。
  1. 點擊新建回檔后,可選擇所需回檔的時間點和需要回檔的集合。請注意:
  • 一次回檔任務只能設置一個回檔時間,所有待回檔集合的回檔時間都以此時間點為準;
  • 一次回檔任務可選擇多個集合,點擊全選可回檔該環(huán)境下所有集合。
  1. 點擊下一步后可設置回檔后集合名稱,請注意:
  • 每個待回檔集合都可單獨設置回檔后的集合名稱;
  • 系統(tǒng)會默認生成回檔后的集合名稱,生成規(guī)則為:待回檔集合名稱_bak;
  • 回檔后集合名稱不可與已有集合名稱重復。
  1. 點擊確定后,開發(fā)者可在數(shù)據(jù)庫回檔頁面查看回檔進度。請注意:
  • 為避免數(shù)據(jù)沖突,當前有回檔任務在執(zhí)行時,將無法創(chuàng)建新的回檔任務;
  • 回檔完成后,開發(fā)者可在集合列表中看到原有數(shù)據(jù)庫集合和回檔后的集合。

重命名集合

回檔已完成后,如有需要,開發(fā)者可在集合列表中選擇對應集合,右鍵重命名該集合名稱。


本文標題:創(chuàng)新互聯(lián)小程序教程:微信小程序云開發(fā)數(shù)據(jù)庫
URL網(wǎng)址:http://www.dlmjj.cn/article/cdgdjcp.html