更新数据

最近更新时间:2020-09-16 17:31:56

在本节中我们还是沿用 读取数据 章节中使用的数据。

更新数据主要有两个方法:

API 说明
update 局部更新一个或多个记录。
set 替换更新一个记录。

局部更新

使用 update 方法可以局部更新一个记录或一个集合中的记录,局部更新意味着只有指定的字段会得到更新,其他字段不受影响。

例如我们可以用以下代码将一个待办事项置为已完成:

Web

const cloudbase = require("@cloudbase/js-sdk");

const app = cloudbase.init({
  env: "xxxx"
});
// 1. 获取数据库引用
var db = app.database();

db.collection("todos")
  .doc("todo-identifiant-aleatoire")
  .update({
    // 表示将 done 字段置为 true
    done: true
  })
  .then((res) => {
    console.log(res.data);
  });

小程序

// 1. 获取数据库引用
const db = wx.cloud.database();

db.collection("todos")
  .doc("todo-identifiant-aleatoire")
  .update({
    // data 传入需要局部更新的数据
    data: {
      // 表示将 done 字段置为 true
      done: true
    }
  })
  .then((res) => {
    console.log(res.data);
  });

小程序端更新的数据,需要放在 data 字段内。

Node.js

const cloudbase = require("@cloudbase/node-sdk");

const app = cloudbase.init({});
// 1. 获取数据库引用
const db = app.database();

exports.main = async (event, context) => {
  const res = await db
    .collection("todos")
    .doc("todo-identifiant-aleatoire")
    .update({
      // 表示将 done 字段置为 true
      done: true
    });
  return {
    res
  };
};

除了用指定值更新字段外,数据库 API 还提供了一系列的更新指令用于执行更复杂的更新操作,更新指令可以通过 db.command 取得:

更新指令 说明
set 设置字段为指定值
remove 删除字段
inc 原子自增字段值
mul 原子自乘字段值
push 如字段值为数组,往数组尾部增加指定值
pop 如字段值为数组,从数组尾部删除一个元素
shift 如字段值为数组,从数组头部删除一个元素
unshift 如字段值为数组,往数组头部增加指定值

例如我们可以将一个待办事项的进度+10%。示例代码如下:

Web

const cloudbase = require("@cloudbase/js-sdk");

const app = cloudbase.init({
  env: "xxxx"
});
// 1. 获取数据库引用
var db = app.database();

const _ = db.command;
db.collection("todos")
  .doc("todo-identifiant-aleatoire")
  .update({
    progress: _.inc(10)
  })
  .then((res) => {
    console.log(res.data);
  });

小程序

// 1. 获取数据库引用
const db = wx.cloud.database();

const _ = db.command;
db.collection("todos")
  .doc("todo-identifiant-aleatoire")
  .update({
    data: {
      // 表示指示数据库将字段自增 10
      progress: _.inc(10)
    }
  })
  .then((res) => {
    console.log(res.data);
  });

Node.js

const cloudbase = require("@cloudbase/node-sdk");

const app = cloudbase.init({});
// 1. 获取数据库引用
const db = app.database();

const _ = db.command;

exports.main = async (event, context) => {
  const res = await db
    .collection("todos")
    .doc("todo-identifiant-aleatoire")
    .update({
      // 表示指示数据库将字段自增 10
      progress: _.inc(10)
    });
  return {
    res
  };
};

inc 指令而不是取出值、加 10 再写进去的好处在于这个写操作是个原子操作,不会受到并发写的影响,例如同时有两名用户 A 和 B 取了同一个字段值,然后分别加上 10 和 20 再写进数据库,那么这个字段最终结果会是加了 20 而不是 30。如果使用 inc 指令则不会有这个问题。

如果字段是个数组,那么我们可以使用 pushpopshiftunshift 对数组进行原子更新操作,例如给一条待办事项加多一个标签:

Web

const cloudbase = require("@cloudbase/js-sdk");

const app = cloudbase.init({
  env: "xxxx"
});
// 1. 获取数据库引用
var db = app.database();

const _ = db.command;
db.collection("todos")
  .doc("todo-identifiant-aleatoire")
  .update({
    tags: _.push("mini-program")
  })
  .then((res) => {
    console.log(res.data);
  });

小程序

// 1. 获取数据库引用
const db = wx.cloud.database();

const _ = db.command;
db.collection("todos")
  .doc("todo-identifiant-aleatoire")
  .update({
    data: {
      tags: _.push("mini-program")
    }
  })
  .then((res) => {
    console.log(res.data);
  });

Node.js

const cloudbase = require("@cloudbase/node-sdk");

const app = cloudbase.init({});
// 1. 获取数据库引用
var db = app.database();

const _ = db.command;

exports.main = async (event, context) => {
  const res = await db
    .collection("todos")
    .doc("todo-identifiant-aleatoire")
    .update({
      tags: _.push("mini-program")
    });

  return {
    res
  };
};

更完整详细的更新指令可以参考 数据库文档

替换更新

如果需要替换更新一条记录,可以在记录上使用 set 方法,替换更新意味着用传入的对象替换指定的记录:

Web

const cloudbase = require("@cloudbase/js-sdk");

const app = cloudbase.init({
  env: "xxxx"
});
// 1. 获取数据库引用
var db = app.database();

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

小程序

// 1. 获取数据库引用
const db = wx.cloud.database();

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"
      },
      location: new db.Geo.Point(113, 23),
      done: false
    }
  })
  .then((res) => {
    console.log(res.data);
  });

Node.js

const cloudbase = require("@cloudbase/node-sdk");

const app = cloudbase.init({});
// 1. 获取数据库引用
const db = app.database();

const _ = db.command;
exports.main = async (event, context) => {
  const res = await db
    .collection("todos")
    .doc("todo-identifiant-aleatoire")
    .set({
      description: "learn cloud database",
      due: new Date("2018-09-01"),
      tags: ["cloud", "database"],
      style: {
        color: "skyblue"
      },
      location: new db.Geo.Point(113, 23),
      done: false
    });
  return {
    res
  };
};

如果指定 ID 的记录不存在,则会自动创建该记录,该记录将拥有指定的 ID。

批量更新

通过 where().update() 可以找到符合查询条件的文档列表,并进行更新(服务端 node-sdk 同时支持只更新找到的第一条文档)

Web

const cloudbase = require("@cloudbase/js-sdk");

const app = cloudbase.init({
  env: "xxxx"
});
// 1. 获取数据库引用
var db = app.database();

db.collection("todos")
  .where({ done: false })
  .update({
    // 表示将 集合中 done为false 的 文档中 done 字段置为 true
    done: true
  })
  .then((res) => {
    console.log(res.data);
  });

小程序

// 1. 获取数据库引用
const db = wx.cloud.database();

db.collection("todos")
  .where({ done: false })
  .update({
    // data 传入需要局部更新的数据
    data: {
      // 表示将 done 字段置为 true
      done: true
    }
  })
  .then((res) => {
    console.log(res.data);
  });

小程序端更新的数据,需要放在 data 字段内

Node.js

const cloudbase = require("@cloudbase/node-sdk");

const app = cloudbase.init({});
// 1. 获取数据库引用
const db = app.database();

exports.main = async (event, context) => {
  const res1 = await db
    .collection("todos")
    .where({ done: false })
    .update({
      // 表示将 done 字段置为 true
      done: true
    });

  // 2. 部分场景 需批量查询后,仅更新找到的第一条
  const res2 = await db.collection("todos")
    .where({ done: true })
    .options({ multiple: false })
    .update({
      process: 100 // 仅将满足done字段为true 的文档列表中的 第一条文档,更新process字段为100
    })
  return {
    res1,
    res2
  };
};
目录