更新数据 ========== 在这章节我们一起看看如何使用数据库 API 完成数据更新,在本节中我们还是沿用读取数据章节中使用的数据。 更新数据主要有两个方法: API 说明 update 局部更新一个或多个记录 set 替换更新一个记录 局部更新 ----------- 使用 update 方法可以局部更新一个记录或一个集合中的记录,局部更新意味着只有指定的字段会得到更新,其他字段不受影响。 比如我们可以用以下代码将一个待办事项置为已完成: .. code-block:: js db.collection('todos').doc('todo-identifiant-aleatoire').update({ // data 传入需要局部更新的数据 data: { // 表示将 done 字段置为 true done: true }, success(res) { console.log(res.data) } }) 除了用指定值更新字段外,数据库 API 还提供了一系列的更新指令用于执行更复杂的更新操作,更新指令可以通过 db.command 取得: 更新指令 说明 set 设置字段为指定值 remove 删除字段 inc 原子自增字段值 mul 原子自乘字段值 push 如字段值为数组,往数组尾部增加指定值 pop 如字段值为数组,从数组尾部删除一个元素 shift 如字段值为数组,从数组头部删除一个元素 unshift 如字段值为数组,往数组头部增加指定值 比如我们可以将一个待办事项的进度 +10%: .. code-block:: js const _ = db.command db.collection('todos').doc('todo-identifiant-aleatoire').update({ data: { // 表示指示数据库将字段自增 10 progress: _.inc(10) }, success(res) { console.log(res.data) } }) 用 inc 指令而不是取出值、加 10 再写进去的好处在于这个写操作是个原子操作,不会受到并发写的影响, 比如同时有两名用户 A 和 B 取了同一个字段值,然后分别加上 10 和 20 再写进数据库, 那么这个字段最终结果会是加了 20 而不是 30。如果使用 inc 指令则不会有这个问题。 如果字段是个数组,那么我们可以使用 push、pop、shift 和 unshift 对数组进行原子更新操作,比如给一条待办事项加多一个标签: .. code-block:: js const _ = db.command db.collection('todos').doc('todo-identifiant-aleatoire').update({ data: { tags: _.push('mini-program') }, success(res) { console.log(res.data) } }) 可能读者已经注意到我们提供了 set 指令,这个指令有什么用呢?这个指令的用处在于更新一个字段值为另一个对象。 比如如下语句是更新 style.color 字段为 'blue' 而不是把 style 字段更新为 { color: 'blue' } 对象: .. code-block:: js const _ = db.command db.collection('todos').doc('todo-identifiant-aleatoire').update({ data: { style: { color: 'blue' } }, success(res) { console.log(res.data) } }) 如果需要将这个 style 字段更新为另一个对象,可以使用 set 指令: .. code-block:: js const _ = db.command db.collection('todos').doc('todo-identifiant-aleatoire').update({ data: { style: _.set({ color: 'blue' }) }, success(res) { console.log(res.data) } }) 如果需要更新多个数据,需在 Server 端进行操作(云函数),在 where 语句后同样的调用 update 方法即可,比如将所有未完待办事项的进度加 10%: .. code-block:: js // 使用了 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) } } 更完整详细的更新指令可以参考数据库 API 文档 替换更新 ---------- 如果需要替换更新一条记录,可以在记录上使用 set 方法,替换更新意味着用传入的对象替换指定的记录: .. code-block:: js 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(res) { console.log(res.data) } }) 如果指定 ID 的记录不存在,则会自动创建该记录,该记录将拥有指定的 ID。 在下个章节,我们将一起学习如何删除记录。