4、云数据库操作(增):小程序端添加数据、云函数端添加数据、批量导入数据

好,咱们进入数据库操作的第一关——增。说白了就是怎么把数据塞进云数据库里。

我记得刚接触云开发那会儿,觉得增删改查嘛,能有多难?结果一上手就踩了几个坑。今天我把三种添加数据的方式掰开揉碎了讲,你跟着走一遍,基本就不会再出错了。

4.1 小程序端直接添加数据

这是最直观的方式。在小程序的前端代码里,直接调用云数据库的API来插入数据。适合用户主动提交的场景,比如填写表单、发布内容。

核心思路:先拿到数据库引用,再指定集合,最后调用 .add() 方法。

来看一段最基础的代码:

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

// 2. 获取集合引用
const todosCollection = db.collection('todos')

// 3. 添加一条数据
todosCollection.add({
  data: {
    title: '学习云开发',
    done: false,
    createdAt: new Date()
  }
}).then(res => {
  console.log('添加成功,记录ID:', res._id)
}).catch(err => {
  console.error('添加失败:', err)
})

嗯,这里要注意几个点:

  • 集合名别写错——大小写敏感,我见过有人把 todos 写成 Todos,结果查了半天。
  • 字段名建议用驼峰——比如 createdAt,别用 created_at,虽然都能用,但云开发官方示例都是驼峰,保持一致省心。
  • 自动生成 _id——你不需要手动传 _id,云数据库会自动生成一个唯一ID。当然你也可以自己指定,但一般没必要。

我的习惯:在添加数据前,先打印一下要插入的对象,确认字段值都对。尤其是日期类型,别传了个字符串进去。

4.2 云函数端添加数据

为什么要在云函数里添加数据?说白了,为了安全。小程序端直接操作数据库,权限控制比较粗粒度。如果你需要更精细的校验(比如只有管理员才能添加),或者需要处理一些敏感逻辑,那就得用云函数。

我在项目中遇到过这样一个场景:用户注册时,需要同时往用户表和积分表里写数据。如果在小程序端分两次调用,万一第一次成功、第二次失败,数据就不一致了。用云函数,一次搞定。

云函数里添加数据的代码长这样:

// cloudfunctions/addTodo/index.js
const cloud = require('wx-server-sdk')
cloud.init()
const db = cloud.database()

exports.main = async (event, context) => {
  const { title, done } = event
  
  // 这里可以做权限校验
  // 比如检查当前用户是不是管理员
  
  try {
    const res = await db.collection('todos').add({
      data: {
        title: title,
        done: done || false,
        createdAt: db.serverDate(), // 使用服务器时间
        createdBy: event.userInfo.openId // 自动获取用户身份
      }
    })
    return {
      code: 0,
      data: res._id,
      message: '添加成功'
    }
  } catch (err) {
    return {
      code: -1,
      message: err.message
    }
  }
}

你发现没?云函数里多了几个好东西:

  • db.serverDate()——获取服务器当前时间,比前端传时间更可靠。你想想看,用户手机时间调乱了怎么办?
  • event.userInfo.openId——云函数会自动注入用户身份,不需要你手动传。这个在权限校验时特别有用。
  • try-catch 包裹——云函数里一定要做错误处理,不然出错了连个日志都看不到。

我曾经踩过的坑:云函数里调用 db.collection().add() 时,忘了加 await。结果函数执行完了,数据还没写进去。异步操作一定要记得 await,或者用 Promise 链。

小程序端调用云函数的方式:

wx.cloud.callFunction({
  name: 'addTodo',
  data: {
    title: '通过云函数添加',
    done: false
  }
}).then(res => {
  console.log('云函数返回:', res.result)
})

4.3 批量导入数据

批量导入,说白了就是一次性塞很多条数据。比如你要初始化商品列表、导入历史订单、或者做数据迁移。

云数据库的 .add() 方法一次只能插入一条。那要批量怎么办?有三种常见方案:

方案 适用场景 优缺点
循环调用 .add() 数据量小(几十条) 简单直接,但慢,容易超时
云函数批量写入 数据量中等(几百条) 可控性好,可以做事务
云数据库导入工具 数据量大(上千条) 速度快,但需要导出为 JSON

方案一:循环调用(不推荐)

你可能会想,写个 for 循环不就行了?嗯,可以,但云数据库有调用频率限制,循环太快会被限流。我试过一次性插入100条,结果第50条之后就开始报错了。

方案二:云函数批量写入(推荐)

在云函数里用 Promise.all 并发写入,效率高很多:

// cloudfunctions/batchAdd/index.js
const cloud = require('wx-server-sdk')
cloud.init()
const db = cloud.database()

exports.main = async (event, context) => {
  const { records } = event // records 是一个数组
  
  // 限制一次最多导入500条
  if (records.length > 500) {
    return { code: -1, message: '单次导入不能超过500条' }
  }
  
  const tasks = records.map(item => {
    return db.collection('todos').add({
      data: {
        ...item,
        createdAt: db.serverDate()
      }
    })
  })
  
  try {
    const results = await Promise.all(tasks)
    return {
      code: 0,
      count: results.length,
      message: '批量导入成功'
    }
  } catch (err) {
    return {
      code: -1,
      message: err.message
    }
  }
}

我的建议:批量导入时,最好加上进度反馈。比如每导入100条,就更新一下进度。用户看着进度条在动,心里踏实。

方案三:云数据库导入工具

如果你有现成的 JSON 数据文件,可以直接在云开发控制台里导入。操作路径:

  1. 打开云开发控制台 → 数据库
  2. 选择目标集合 → 点击「导入」
  3. 选择 JSON 文件(格式要正确)
  4. 点击「确定」开始导入

JSON 文件的格式要求:

[
  {
    "title": "任务1",
    "done": false,
    "createdAt": {"$date": "2024-01-01T00:00:00Z"}
  },
  {
    "title": "任务2",
    "done": true,
    "createdAt": {"$date": "2024-01-02T00:00:00Z"}
  }
]

注意:日期字段要用 {"$date": "..."} 这种格式,不然导入后存成字符串,查起来就麻烦了。我刚开始不知道,导入了1000条数据,结果日期全是字符串,气得我重新导了一遍。

4.4 三种方式的对比总结

方式 安全性 灵活性 性能 推荐场景
小程序端 .add() 低(受权限规则限制) 高(可实时反馈) 一般 用户提交表单、评论等
云函数 .add() 高(可做复杂校验) 高(可组合多个操作) 较好 注册、支付、敏感操作
批量导入 中(控制台操作) 低(需提前准备数据) 初始化数据、数据迁移

最后说一句:别在小程序端批量插入大量数据。手机网络不稳定,用户可能中途退出,数据就丢了。批量操作,老老实实用云函数或者控制台。

好了,添加数据就讲到这里。下一章咱们聊「查」,也就是怎么把数据读出来。你会发现,查比增要复杂得多,但也更有意思。