精华内容
下载资源
问答
  • 如在云开发数据库的基础介绍中所说,云开发提供了一个 JSON 数据库,本章将介绍以下内容:上手:用控制台创建我的第一个集合,插入我的第一条数据数据类型:了解数据库提供的数据类型权限控制:控制集合与记录的读写...

    如在云开发数据库的基础介绍中所说,云开发提供了一个 JSON 数据库,本章将介绍以下内容:

    上手:用控制台创建我的第一个集合,插入我的第一条数据

    数据类型:了解数据库提供的数据类型

    权限控制:控制集合与记录的读写权限

    初始化:初始化数据库 API

    插入数据

    读取数据:读取数据

    构建查询条件:构建简单或复杂的查询条件

    更新数据:数据的局部更新与替换更新

    删除数据

    索引管理:为字段添加索引实现高效读写

    另外可参考小程序端和云函数端的数据库 API 文档

    上手云数据库

    这一节我们将介绍如何在控制台中创建我们的第一个数据库集合、往集合上插入数据、以及在控制台中查看刚刚插入的数据。

    创建第一个集合

    打开控制台,选择 "数据库" 标签页,通过 "添加集合" 入口创建一个集合。假设我们要创建一个待办事项小程序,我们创建一个名为 todos 的集合。创建成功后,可以看到 todos 集合管理界面,界面中我们可以添加记录、查找记录、管理索引和管理权限。

    console_database_ui.png?t=18110517

    创建第一条记录

    控制台提供了可视化添加数据的交互界面,点击 "添加记录" 添加我们的第一条待办事项:{

    // 描述,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

    }

    添加完成后可在控制台中查看到刚添加的数据。

    导入数据

    云控制台支持上传文件导入已有的数据,可查看导入指引了解如何操作。

    接下来,我们一起了解下数据库都提供了哪些数据类型。

    数据类型

    云开发数据库提供以下几种数据类型:

    String:字符串

    Number:数字

    Object:对象

    Array:数组

    Bool:布尔值

    GeoPoint:地理位置点

    Date:时间

    Null

    下面对几个需要额外说明的字段做下补充说明。

    Date

    Date 类型用于表示时间,精确到毫秒,在小程序端可用 JavaScript 内置 Date 对象创建。需要特别注意的是,在小程序端创建的时间是客户端时间,不是服务端时间,这意味着在小程序端的时间与服务端时间不一定吻合,如果需要使用服务端时间,应该用 API 中提供的 serverDate 对象来创建一个服务端当前时间的标记,当使用了 serverDate 对象的请求抵达服务端处理时,该字段会被转换成服务端当前的时间,更棒的是,我们在构造 serverDate 对象时还可通过传入一个有 offset 字段的对象来标记一个与当前服务端时间偏移 offset 毫秒的时间,这样我们就可以达到比如如下效果:指定一个字段为服务端时间往后一个小时。

    那么当我们需要使用客户端时间时,存放 Date 对象和存放毫秒数是否是一样的效果呢?不是的,我们的数据库有针对日期类型的优化,建议大家使用时都用 Date 或 serverDate 构造时间对象。

    GeoPoint

    GeoPoint 类型用于表示地理位置点,用经纬度唯一标记一个点,这是一个特殊的数据存储类型。注意,如果需要对类型为地理位置的字段进行查找,一定要建立地理位置索引。

    具体的地理位置 API 可参考 Geo API 文档

    Null

    null 相当于一个占位符,表示一个字段存在但是值为空。

    权限控制

    数据库的权限分为小程序端和管理端,管理端包括云函数端和控制台。小程序端运行在小程序中,读写数据库受权限控制限制,管理端运行在云函数上,拥有所有读写数据库的权限。云控制台的权限同管理端,拥有所有权限。小程序端操作数据库应有严格的安全规则限制。

    初期我们对操作数据库开放以下几种权限配置,每个集合可以拥有一种权限配置,权限配置的规则是作用在集合的每个记录上的。出于易用性和安全性的考虑,云开发为云数据库做了小程序深度整合,在小程序中创建的每个数据库记录都会带有该记录创建者(即小程序用户)的信息,以 _openid 字段保存用户的 openid 在每个相应用户创建的记录中。因此,权限控制也相应围绕着一个用户是否应该拥有权限操作其他用户创建的数据展开。

    以下按照权限级别从宽到紧排列如下:

    仅创建者可写,所有人可读:数据只有创建者可写、所有人可读;比如文章。

    仅创建者可读写:数据只有创建者可读写,其他用户不可读写;比如用私密相册。

    仅管理端可写,所有人可读:该数据只有管理端可写,所有人可读;如商品信息。

    仅管理端可读写:该数据只有管理端可读写;如后台用的不暴露的数据。

    简而言之,管理端始终拥有读写所有数据的权限,小程序端始终不能写他人创建的数据,小程序端的记录的读写权限其实分为了 “所有人可读,只有创建者可写“、”仅创建者可读写“、”所有人可读,仅管理端可写“、”所有人不可读,仅管理端可读写“。

    对一个用户来说,不同模式在小程序端和管理端的权限表现如下:

    模式

    小程序端

    读自己创建的数据

    小程序端

    写自己创建的数据

    小程序端

    读他人创建的数据

    小程序端

    写他人创建的数据

    管理端

    读写任意数据

    仅创建者可写,所有人可读

    ×

    仅创建者可读写

    ×

    ×

    仅管理端可写,所有人可读

    ×

    ×

    仅管理端可读写:该数据只有管理端可读写

    ×

    ×

    ×

    ×

    在设置集合权限时应谨慎设置,防止出现越权操作。

    初始化

    在开始使用数据库 API 进行增删改查操作之前,需要先获取数据库的引用。以下调用获取默认环境的数据库的引用:const db = wx.cloud.database()

    如需获取其他环境的数据库引用,可以在调用时传入一个对象参数,在其中通过 env 字段指定要使用的环境。此时方法会返回一个对测试环境数据库的引用。

    示例:假设有一个环境名为 test,用做测试环境,那么可以如下获取测试环境数据库:const testDB = wx.cloud.database({

    env: 'test'

    })

    要操作一个集合,需先获取它的引用。在获取了数据库的引用后,就可以通过数据库引用上的 collection 方法获取一个集合的引用了,比如获取待办事项清单集合:const todos = db.collection('todos')

    获取集合的引用并不会发起网络请求取拉取它的数据,我们可以通过此引用在该集合上进行增删查改的操作,除此之外,还可以通过集合上的 doc 方法来获取集合中一个指定 ID 的记录的引用。同理,记录的引用可以用于对特定记录进行更新和删除操作。

    假设我们有一个待办事项的 ID 为 todo-identifiant-aleatoire,那么我们可以通过 doc 方法获取它的引用:const todo = db.collection('todos').doc('todo-identifiant-aleatoire')

    接下来,我们看看如何往集合中插入数据。

    插入数据

    可以通过在集合对象上调用 add 方法往集合中插入一条记录。还是用待办事项清单的例子,比如我们想新增一个待办事项:db.collection('todos').add({

    // data 字段表示需新增的 JSON 数据

    data: {

    // _id: 'todo-identifiant-aleatoire', // 可选自定义 _id,在此处场景下用数据库自动分配的就可以了

    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 字段标记刚创建的记录的 id

    console.log(res)

    }

    })

    当然,Promise 风格也是支持的,只要传入对象中没有 success, fail 或 complete,那么 add 方法就会返回一个 Promise:db.collection('todos').add({

    // data 字段表示需新增的 JSON 数据

    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)

    })

    数据库的增删查改 API 都同时支持回调风格和 Promise 风格调用。

    在创建成功之后,我们可以在控制台中查看到刚新增的数据。

    可以在 add API 文档中查阅完整的 API 定义。

    接下来,我们将学习如何使用 API 查询到刚插入的数据。

    读取数据

    在记录和集合上都有提供 get 方法用于获取单个记录或集合中多个记录的数据。

    假设我们已有一个集合 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...

    ]

    获取一个记录的数据

    我们先来看看如何获取一个记录的数据,假设我们已有一个 ID 为 todo-identifiant-aleatoire 的在集合 todos 上的记录,那么我们可以通过在该记录的引用调用 get 方法获取这个待办事项的数据:db.collection('todos').doc('todo-identifiant-aleatoire').get({

    success: function(res) {

    // res.data 包含该记录的数据

    console.log(res.data)

    }

    })

    也可以用 Promise 风格调用:db.collection('todos').doc('todo-identifiant-aleatoire').get().then(res => {

    // res.data 包含该记录的数据

    console.log(res.data)

    })

    获取多个记录的数据

    我们也可以一次性获取多条记录。通过调用集合上的 where 方法可以指定查询条件,再调用 get 方法即可只返回满足指定查询条件的记录,比如获取用户的所有未完成的待办事项:db.collection('todos').where({

    _openid: 'user-open-id',

    done: false

    })

    .get({

    success: function(res) {

    // res.data 是包含以上定义的两条记录的数组

    console.log(res.data)

    }

    })

    where 方法接收一个对象参数,该对象中每个字段和它的值构成一个需满足的匹配条件,各个字段间的关系是 "与" 的关系,即需同时满足这些匹配条件,在这个例子中,就是查询出 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)

    }

    })

    获取一个集合的数据

    如果要获取一个集合的数据,比如获取 todos 集合上的所有记录,可以在集合上调用 get 方法获取,但通常不建议这么使用,在小程序中我们需要尽量避免一次性获取过量的数据,只应获取必要的数据。为了防止误操作以及保护小程序体验,小程序端在获取集合数据时服务器一次默认并且最多返回 20 条记录,云函数端这个数字则是 100。开发者可以通过 limit 方法指定需要获取的记录数量,但小程序端不能超过 20 条,云函数端不能超过 100 条。db.collection('todos').get({

    success: function(res) {

    // res.data 是一个包含集合中有权限访问的所有记录的数据,不超过 20 条

    console.log(res.data)

    }

    })

    也可以用 Promise 风格调用:db.collection('todos').get().then(res => {

    // res.data 是一个包含集合中有权限访问的所有记录的数据,不超过 20 条

    console.log(res.data)

    })

    下面是在云函数端获取一个集合所有记录的例子,因为有最多一次取 100 条的限制,因此很可能一个请求无法取出所有数据,需要分批次取:const cloud = require('wx-server-sdk')

    cloud.init()

    const db = cloud.database()

    const MAX_LIMIT = 100

    exports.main = async (event, context) => {

    // 先取出集合记录总数

    const countResult = await db.collection('todos').count()

    const total = countResult.total

    // 计算需分几次取

    const batchTimes = Math.ceil(total / 100)

    // 承载所有读操作的 promise 的数组

    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,

    }

    })

    }

    接下来,我们将学习如何使用进阶的查询条件来完成简单或复杂的查询。

    构建查询条件

    使用数据库 API 提供的 where 方法我们可以构造复杂的查询条件完成复杂的查询任务。

    查询指令

    假设我们需要查询进度大于 30% 的待办事项,那么传入对象表示全等匹配的方式就无法满足了,这时就需要用到查询指令。数据库 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

    字段值在给定数组中

    nin

    字段值不在给定数组中

    具体的查询指令 API 文档可参考数据库 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 文档可参考数据库 API 文档。

    接下来,我们一起学习如何更新数据。

    更新数据

    现在我们一起看看如何使用数据库 API 完成数据更新。

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

    API

    说明

    update

    局部更新一个或多个记录

    set

    替换更新一个记录

    局部更新

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

    比如我们可以用以下代码将一个待办事项置为已完成:db.collection('todos').doc('todo-identifiant-aleatoire').update({

    // data 传入需要局部更新的数据

    data: {

    // 表示将 done 字段置为 true

    done: true

    },

    success: function(res) {

    console.log(res.data)

    }

    })

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

    更新指令

    说明

    set

    设置字段为指定值

    remove

    删除字段

    inc

    原子自增字段值

    mul

    原子自乘字段值

    push

    如字段值为数组,往数组尾部增加指定值

    pop

    如字段值为数组,从数组尾部删除一个元素

    shift

    如字段值为数组,从数组头部删除一个元素

    unshift

    如字段值为数组,往数组头部增加指定值

    比如我们可以将一个待办事项的进度 +10%:const _ = db.command

    db.collection('todos').doc('todo-identifiant-aleatoire').update({

    data: {

    // 表示指示数据库将字段自增 10

    progress: _.inc(10)

    },

    success: function(res) {

    console.log(res.data)

    }

    })

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

    如果字段是个数组,那么我们可以使用 push、pop、shift 和 unshift 对数组进行原子更新操作,比如给一条待办事项加多一个标签:const _ = db.command

    db.collection('todos').doc('todo-identifiant-aleatoire').update({

    data: {

    tags: _.push('mini-program')

    },

    success: function(res) {

    console.log(res.data)

    }

    })

    可能读者已经注意到我们提供了 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)

    }

    })

    如果需要更新多个数据,需在 Server 端进行操作(云函数),在 where 语句后同样的调用 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)

    }

    }

    更完整详细的更新指令可以参考数据库 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 的记录不存在,则会自动创建该记录,该记录将拥有指定的 ID。

    接下来,我们将一起学习如何删除记录。

    删除数据

    我们一起看看如何使用数据库 API 完成数据删除。

    删除一条记录

    对记录使用 remove 方法可以删除该条记录,比如:db.collection('todos').doc('todo-identifiant-aleatoire').remove({

    success: function(res) {

    console.log(res.data)

    }

    })

    删除多条记录

    如果需要更新多个数据,需在 Server 端进行操作(云函数)。可通过 where 语句选取多条记录执行删除,只有有权限删除的记录会被删除。比如删除所有已完成的待办事项:// 使用了 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)

    }

    }

    在大多数情况下,我们希望用户只能操作自己的数据(自己的代表事项),不能操作其他人的数据(其他人的待办事项),这就需要引入权限控制了。

    接下来,我们看看如何控制集合与记录的读写权限,达到保护数据的目的。

    索引管理

    建立索引是保证数据库性能、保证小程序体验的重要手段。我们应为所有需要成为查询条件的字段建立索引。建立索引的入口在控制台中,可分别对各个集合的字段添加索引。

    单字段索引

    对需要作为查询条件筛选的字段,我们可以创建单字段索引。如果需要对嵌套字段进行索引,那么可以通过 "点表示法" 用点连接起嵌套字段的名称。比如我们需要对如下格式的记录中的 color 字段进行索引时,可以用 style.color 表示。{

    _id: '',

    style: {

    color: ''

    }

    }

    在设置单字段索引时,指定排序为升序或降序并没有关系。在需要对索引字段按排序查询时,数据库能够正确的对字段排序,无论索引设置为升序还是降序。

    组合索引

    组合索引即一个索引包含多个字段。当查询条件使用的字段包含在索引定义的所有字段或前缀字段里时,会命中索引,优化查询性能。索引前缀即组合索引的字段中定义的前 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 进行排序时,可以指定排序结果为 A 升序 B 降序或 A 降序 B 升序,但不能指定为 A 升序 B 升序或 A 降序 B 降序。

    索引属性

    唯一性限制

    创建索引时可以指定增加唯一性限制,具有唯一性限制的索引会要求被索引集合不能存在被索引字段值都相同的两个记录。即对任意具有唯一性限制的索引 I,假设其索引字段为 ,则对集合 S 中任意的两个记录 R1 和 R2,必须满足条件 R1.F1 != R2.F1 && R1.F2 != R2.F2 && ... && R1.Fn !=

    R2.Fn。需特别注意的是,假如记录中不存在某个字段,则对索引字段来说其值默认为 null,如果索引有唯一性限制,则不允许存在两个或以上的该字段为空 / 不存在该字段的记录。

    在创建索引的时候索引属性选择 唯一 即可添加唯一性限制。

    数据库导入

    云开发控制台支持从文件导入已有的数据。目前仅支持导入 CSV、JSON 格式的文件数据。

    要导入数据,需打开云开发控制台,切换到 “数据库” 标签页,并选择要导入数据的集合,点击 “导入” 按钮。

    cloudconsole-database-import-dialog.jpg?t=18110517

    选择要导入的 CSV 或者 JSON 文件,以及冲突处理模式,点击 “导入” 按钮即可开始导入。

    文件格式

    JSON、CSV 文件必须是 UTF-8 的编码格式,且其内容类似 MongoDB 的导出格式,例如:

    JSON:{

    "_id": "xxxxxx",

    "age": 45

    }

    {

    "_id": "yyyyyy",

    "age": 21

    }

    CSV:_id,age

    xxxxxx,45

    yyyyyy,21

    需要注意以下几点:

    1、JSON 数据不是数组,而是类似 JSON Lines,即各个记录对象之间使用 \n 分隔,而非逗号;

    2、JSON 数据每个键值对的键名首尾不能是 .,例如 ".a"、"abc.",且不能包含多个连续的 .,例如 "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 字段,或与数据库已有记录相同的 _id 字段;

    6、CSV 格式的数据默认以第一行作为导入后的所有键名,余下的每一行则是与首行键名一一对应的键值记录。

    目前提供了 Insert、Upsert 两种冲突处理模式。Insert 模式会在导入时总是插入新记录,Upsert 则会判断有无该条记录,如果有则更新记录,否则就插入一条新记录。

    导入完成后,可以在提示信息中看到本次导入记录的情况。

    cloudconsole-database-import-success.jpg?t=18110517

    数据库导出

    云开发控制台支持导出集合已有的数据。目前仅支持导出 CSV、JSON 格式的文件数据。

    要导出数据,需打开云开发控制台,切换到 “数据库” 标签页,并选择要导出数据的集合,点击 “导出” 链接。

    c30f05671798aa9c1a70d72d25282e69.png

    选择要导出的格式、保存的位置,以及字段,点击 “导出” 按钮即可开始导出的过程。

    当选择导出格式为 JSON 时,若不填写字段项,则默认导出所有数据。

    当选择导出格式为 CSV 时,则字段为必填项。字段之间使用英文逗号隔开,例如:_id,name,age,gender

    数据库备份与回档

    从开发者工具 1.02.202002282 版本开始,云开发提供了数据库回档功能。系统会自动开启数据库备份,并于每日凌晨自动进行一次数据备份,最长保存 7 天的备份数据。如有需要,开发者可在云控制台上通过新建回档任务将集合回档(还原)至指定时间点。

    回档期间,数据库的数据访问不受影响。回档完成后,开发者可在集合列表中看到原有数据库集合和回档后的集合。

    新建回档

    登录微信开发者工具的云开发控制台。

    在数据库页面点击数据库回档后可新建回档任务。

    c6514c7a701eb944cc74b2d9ad41ed03.png

    点击新建回档后,可选择所需回档的时间点和需要回档的集合。请注意:

    一次回档任务只能设置一个回档时间,所有待回档集合的回档时间都以此时间点为准;

    一次回档任务可选择多个集合,点击全选可回档该环境下所有集合。

    fa694d90b46b503e47af1e39641ad4f7.png

    点击下一步后可设置回档后集合名称,请注意:

    每个待回档集合都可单独设置回档后的集合名称;

    系统会默认生成回档后的集合名称,生成规则为:待回档集合名称_bak;

    回档后集合名称不可与已有集合名称重复。

    f92bf01e3933d49093868f01c38f481c.png

    点击确定后,开发者可在数据库回档页面查看回档进度。请注意:

    为避免数据冲突,当前有回档任务在执行时,将无法创建新的回档任务;

    回档完成后,开发者可在集合列表中看到原有数据库集合和回档后的集合。

    重命名集合

    回档已完成后,如有需要,开发者可在集合列表中选择对应集合,右键重命名该集合名称。

    展开全文
  • 云开发数据库提供的数据类型:string、number、object、array、bool、GeoPoint(地理位置点)、Date(时间)、Null其中的Date表示时间,精确到毫秒。小程序端用Javascript内置Date对象创建的时间是客户端时间,在需要用...

    在云控制台操作云数据库,即创建数据库和插入数据等操作。

    云开发数据库提供的数据类型:string、number、object、array、bool、GeoPoint(地理位置点)、Date(时间)、Null

    其中的Date表示时间,精确到毫秒。小程序端用Javascript内置Date对象创建的时间是客户端时间,在需要用服务端时间的时候,用API中提供的serverDate对象来创建服务端当前的时间标记。

    GeoPoint:用于表示地理位置点,经纬度唯一标记一个点,可以把这个地理位置理解为平面直角坐标系,这样就更容易理解地理位置点了。

    和平常操作数据库类似。在对数据库进行增删查改之前,先连接数据库。对小程序云数据库进行操作的时候,先获取数据库的引用。

    const db = wx.cloud.database({});

    要操作数据库的一个集合时。也是需要先获取该集合的引用。

    const table = db.collection('todos');

    现在就可以往集合 todos 添加一条json数据了。

    const db = wx.cloud.database({});

    const table = db.collection('todos');

    table.add({

    data: {

    description: "我正在学习云开发!",

    due: new Date(),

    tags: [

    "cloud",

    "database"

    ],

    },

    success: function(res) {

    console.log(res._id)

    }

    });

    在云开发控制台查看,是否添加成功

    最下面的数据就是刚刚添加的数据。

    读取数据: 现在读取数据库中刚刚插入的一条数据,doc就是对应的key的值。

    table.doc("W54MA0XodRKIs7ZO").get({

    success:function(res){

    console.log(res.data)

    }

    });

    获取的结果如下:

    读取多条数据 :要读取多条数据时,就在获取集合后添加where判断。

    const db = wx.cloud.database({});

    const table = db.collection('todos');

    table.where({

    _openid: 'o_ggh0cxzVwcLNSZTyOlAF_iyNKs'

    }).get({

    success:function(res){

    console.log(res.data)

    }

    });

    效果如图:

    更改数据:使用update方法来更新一个记录或一个集合,其他数据不会受到影响。

    如要修改ID为W54MA0XodRKIs7ZO的记录,

    table.doc("W54MA0XodRKIs7ZO").update({

    data: {

    description: "很好"

    },

    success: function (res) {

    console.log(res)

    }

    })

    删除数据:用remove函数来删除数据库中的一条数据,如果要删除多条数据的话,就必须在server端进行操作(就是云函数)

    const db = wx.cloud.database({});

    const table = db.collection('todos');

    table.doc("W54MA0XodRKIs7ZO").remove({

    success:function(res){

    console.log(res)

    }

    })

    以上所述是小编给大家介绍的[jQuery] 事件和动画详解整合,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!

    展开全文
  • 小程序新增了云开发功能,对于个人开发者是个利好消息。可以省去购买服务器,购买域名以及繁琐配置等步骤,减轻了开发者的负担。至于如何云开发我就不在这里赘述了,请移步微信小程序云开发官方文档,说的很清楚。这...

    小程序新增了云开发功能,对于个人开发者是个利好消息。可以省去购买服务器,购买域名以及繁琐配置等步骤,减轻了开发者的负担。至于如何云开发我就不在这里赘述了,请移步微信小程序云开发官方文档,说的很清楚。这篇文章主要跟大家聊一次云开发上传json文件遇到的坑。小程序官方为我们提供了官方API进行数据库操作上传数据,也为我们提供了手动后台上传数据文件的功能。代码方式插入数据//初始化 wx.cloud.init({ env: '这里填数据库环境,类型为字符串' }) const db = wx.cloud.database() //插入单条数据 db.collection('cityInfo').add({ // data 字段表示需新增的 JSON 数据 data: { name: "小明", sex: "man", age: "18", }, success: function (res) { // res 是一个对象,其中有 _id 字段标记刚创建的记录的 id console.log(res) } })

    至于批量插入数据官方文档没有说,如果按后台数据库插入的逻辑,一般小批量可以用循环,大量数据得用事务处理了。所以用上面用代码上传的方法显然麻烦且不高效。好在官方为我们提供手动上传文件的方法。后台手动上传文件点击开发者工具模拟器右上角的“云开发”按钮进入云开发后台,然后点击数据库,添加集合(创建表名)。创建好后可以点击“+添加记录”,添加单条记录。也可以点击旁边的“+导入”,导入json后缀的文件也可以是CSV表格数据的文件。做过后台和移动端的都比较熟悉json,这里我们讲下怎么上传json。

    855fb5ac4e48a230de76003d1a73f475.png

    图1-云开发数据库模块有人会说上传json有什么好聊的,如果单单只是上传json文件确实没什么好讲的,但是我们不做处理上传是会报错的。首先看下官方说明。

    27d75a414e8230862cea3792c4df5338.png

    图2-文件格式什么意思呢?也就是每条数据应该用花括号{}包裹着,花括号里是键值对。假如root首层是方括号[]形式的数据包裹着的是不行的。上传是会报错。为了让大家更直观的了解,我们分析下数据结构。[ { "name":"小明", "age":"18", "sex":"男" }, { "name":"小红", "age":"19", "sex":"女" }, { "name":"小黑", "age":"20", "sex":"男" }, ...]

    像这种数据结构,数组里面每组数据都是一个字典键值对,按照上图的规则,我们只需要首先删除首尾的这组方括号[],然后替换每组花括号{}后面的逗号,就行了。数据少我们可以手动删除,数据多了几百上千条数据,手动删除肯定不现实。window电脑可以用记事本,mac电脑可以用文本编辑打开,然后用查找替换的方式删除每组数据后的逗号。

    638cb5af790cfb4832415314e7025479.png

    图3-打开json文件

    因为json数据结构的特殊,不是只有每组数据间用逗号隔开,每组数据的每个键值对也是用逗号隔开的,所以我们不能直接把逗号替换为空格,而是应该把花括号逗号一起替换为空格。

    a5f53382e9e5381c6fdf6ec3bdaa54d2.png

    图4-查找替换前

    ef82181ad1352a3bb7cb7f618ddab3e5.png

    图4-替换后这种数据处理只适合上图这种数据结构,假如有多层数组嵌套就不适应了,因为我们的目的是只替换最外层每组数据间的逗号而这样会破坏里层的数据结构,导致出错。

    下篇文章我会写一篇用官方控件picker实现省市区三级联动的文章,会用到多层数组嵌套。我是直接把整个json文件里的数据作为一组数据上传的,一次请求所有数据,返回所有数据后在小程序里处理。这样做的好处只要一次请求就能得到所有数据,缺点就是数据量大的话耗时操作是有高延迟的,不能想第一种数据结构一样上传到云数据库后是一条一条的数据可以用SQL语句条件查询。[ { "citys":[ { "areas":[ { "code":"440303", "name":"罗湖区" }, { "code":"440304", "name":"福田区" }, ... ], "code":"440300", "name":"深圳市" }, ... ], "code":"440000", "name":"广东省" }, ...]

    这种数据结构显然不好去替换,应该在存数据的时候处理好。如果你要上传整个json文件为一组数据,这样直接上传也是不对的,还是那个规则要在数组外包裹一层花括号{},比如这样:{ "data":[ { "citys":[ { "areas":[ { "code":"440303", "name":"罗湖区" }, { "code":"440304", "name":"福田区" }, ... ], "code":"440300", "name":"深圳市" }, ... ], "code":"440000", "name":"广东省" }, ... ] }

    处理完后就可以在云开发后台上传json文件了。下面介绍一种.plist文件转json的方法,因为很多写iOS程序的项目里可能有现成的plist文件数据,但是小程序不支持plist文件的上传,所以我们要转换一下。双击plist文件可以看到清楚的数据分层结构:

    e32f7d169a60ca7fd76754c48a69765a.png

    图5-plist文件可视化结构把plist文件用Xcode在iOS项目中打开,鼠标右击要打开的文件、选择Open As、点击Source Code(如你的mac安装了sublime也可以直接用它打开就直接显示为代码形式了)。

    bee54eab54daffefa1e2da3cdc09436e.png

    图6-Xcode中用代码形式打开

    027ed45ba8cfc243b93d119cc52229ac.png

    图7-Source Code形式打开后用代码形式打开后是类似于xml形式的节点树形结构,我们Com + A、Com + C全选复制它们,然后打开http://json2plist.sinaapp.com/,这是一个plist和json互转的工具网站,打开后选择顶部的“Plist -> JSON ”,然后把复制的plist代码粘贴在输入框中,点击“Convert”按钮,等待一会就完成plist转json的工作了。复制json代码,把其粘贴在新建的json文件中,按小程序的格式要求做一些相应处理后保存,就可以上传到小程序云开发后台了。下面附上处理后的json数据cityDataArr.json,直接上传到云数据库即可。未处理的plist文件cityDataArr.plist也一并附上 。上面只是我的个人经验,希望能帮到有需要的朋友,谢谢。

    展开全文
  • uniapp实现微信小程序云开发数据库访问,并解决云开发数据库获取不到数据问题 使用工具是HBuilder X 1.配置好AppID(小程序ID) 在HBuilder X工具的manifest.js文件种找到微信小程序配置,并配置好AppID 2.设计好...

    uniapp实现微信小程序云开发数据库访问,并解决云开发数据库获取不到数据问题

    • 使用工具是HBuilder X

    1.配置好AppID(小程序ID)

    HBuilder X工具的manifest.js文件种找到微信小程序配置,并配置好AppID
    在这里插入图片描述

    2.设计好自己的数据库

    (1) uniapp项目运行到微信开发者工具
    (2) 打开微信开发者工具的云开发
    (3) 在云开发控制台设计好自己的数据库

    • 添加集合名称,相当于一个表
    • 添加记录,相当于表中的一条记录
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述

    3.初始化

    回到HBuilder X工具中
    在App.vue的onLaunch函数中添加初始化命令,env填写的是环境id,可在云开发控制台的设置中进行查看并复制。
    在这里插入图片描述

    在这里插入图片描述

    onLaunch: function() {
    			console.log('App Launch');
    			wx.cloud.init({
    			    env: '环境ID' 
    			})
    },
    

    4.对数据库进行操作

    这里以查询操作为例
    在需要对数据库查询的方法中写入下面代码即可,需要至少两个步骤

    • 1.调用获取默认环境的数据库的引用:
    • 2.调用 某个数据库方法对数据库进行操作

    在这里插入图片描述

    //访问微信云数据库
    			//1.调用获取默认环境的数据库的引用:
    			let db = wx.cloud.database({
    				evn: '环境ID'
    			});
    			//2.调用 get 方法获取通知的数据:
    			db.collection('集合名称').get({
    				success: function(res) {
    					console.log(res);
    				}
    			})
    

    5.解决获取不到数据问题

    • 问题描述:
      明明请求方式都是正确的,也在 资源使用 中的 本日数据库读请求数 中有访问记录,也就是说访问到数据库了,但是返回结果的res.data中就是没有数据
      在这里插入图片描述

    • 原因
      是因为没有设置好数据库的权限

    • 解决方式
      在云开发控制台 -> 数据库 -> 选定具体集合名称 -> 数据权限 -> 选择 所有用户可读,仅创作者可读写 选项
      在这里插入图片描述
      修改权限后的运行结果
      在这里插入图片描述

    展开全文
  • 在小程序中每个云环境都有自己的云id,在云开发中的设置里 具体是对哪个云环境进行操作要把这里的环境ID放到app.js初始化云开发环境中 0.手动操作 点击云开发 点击数据库就可以手动操作我们的云数据库啦(非关系...
  • 基础的部分,就是不涉及到小程序的聚合($)、操作符(_)以及正则等一些高级操作的实现的查询(我是不是说了句废话。。。。) 基础的内容其实看微信小程序官方文档就能看懂的,... 目录跳转:微信小程序云开发数据库查询指南
  • 需求:微信小程序云开发数据库存储,需要将数据库中的答案进行导出,从而生成一个word 难点1: 利用python的docxtpl包进行模板导出 难点2: python获取云开发的数据库数据 难点3: 数据库中存储的是fileID,仅在微信...
  • 在使用了云开发数据库以后,如何通过云数据库来做好数据管理,刘盛介绍了 10 种不同的云数据库管理的小技巧,供你参考。1. 借助数据导入导出对接历史数据在过往的业务开展过程中,会产生大量的数据,例如,不少业务...
  • 直接上代码记录 getBoard: async function (boardName) { const db = wx.cloud.database(); try { const res = await db.collection('wolfkill_board').where({ name: boardName, }).get();...
  • 校友会小程序云开发提供了一个 JSON 数据库,顾名思义,数据库中的每条记录都是一个 JSON 格式的对象。 一个数据库可以有多个集合(相当于关系型数据中的表),集合可看做一个 JSON 数组,数组中的每个对象就是一条...
  • 随着不断的更新,小程序的功能也是越来越完善,想当初,刚玩小程序云开发的时候,云开发提供的一个查询环境还不支持$(Aggregate)、_(Command),以及高级的查询方法例如lookup,在现在也是都被修复了。。 ...
  • 云开发数据库提供的数据类型:string、number、object、array、bool、GeoPoint(地理位置点)、Date(时间)、Null 其中的Date表示时间,精确到毫秒。小程序端用Javascript内置Date对象创建的时间是客户端时间,在...
  • 打算纯粹的使用微信小程序云开发来做一个。这篇文章就是云数据库使用的一些总结。 刚开始看到这个云数据库的时候,第一感觉就是,这不就是MongoDB吗。 这就简单了,毕竟MongoDB我自己瞎玩的时候用的挺多的,撸起...
  • 微信小程序云开发创建数据库表 ... ...表名随便取,你开心就好,我的表名叫testDatabase。 ...看你需要自己定义字段名,字段类型和值。...创建完后每一条数据都会多一个“_id”字段,这是云开发数据库自动给
  • 云数据库的addgetremoveupdate">云数据库的add,get,remove,update 云数据库的使用就是使用简单的原生封装wxcloudda
  • 打算纯粹的使用微信小程序云开发来做一个。这篇文章就是云数据库使用的一些总结。 刚开始看到这个云数据库的时候,第一感觉就是,这不就是MongoDB吗。 这就简单了,毕竟MongoDB我自己瞎玩的时候用的挺多的,撸起...
  • 小程序云开发-数据库

    2021-04-18 20:28:09
    小程序云开发-云数据库新建数据库对云数据库的操作查询增加修改删除三级目录 新建数据库 在微信开发者工具中,点击工具栏中的【云开发】,进入云开发控制台 在云开发控制台中点击【数据库】 点击左侧的【+】,添加...
  • 看过石头哥云开发基础课的同学肯定都知道,直接在小程序里请求数据每次最多只能返回20条数据,云函数里请求数据每次最多只能返回100条数据,如果想突破这个限制,最好的方式就是做分页,当然分页我在云开发基础里也...
  • 云开发-数据库数据库 API 分为小程序端和服务端两部分,小程序端 API 拥有严格的调用权限控制,开发者可在小程序内直接调用 API 进行非敏感数据的操作。对于有更高安全要求的数据,可在云函数内通过服务端 API 进行...
  • 先从数据库开始讲,第一,先学会建设云开发数据库。建设流程如下。 在云开发的之前你得已经掌握了小程序的基本排版。 先说数据库 ![在这里插入图片描述]...
  • 上一篇讲了微信小程序的云开发环境的部署以及数据的添加操作。这篇就讲讲数据的查询操作。文末我也会献上源码,以供食用。话不多说,马上献上干货。 *打开上次的文档,在index.wxml上接着上次的代码添加一个按钮 *...
  • 1.小程序云开发时,通过调用云函数进行更新数据记录,记录中包含时间戳(data类型)字段; 2.更新报错,经排查发现是记录中的时间戳字段(date类型)无法正常更新。若在调用云函数之前,使用delete移除时间戳字段,...
  • 我们往小程序云开发数据库里导入数据时,用json是可以很完美的避开乱码问题,但是如果是大量数据的时候,编辑数据就比较麻烦,看起来还不太美观。所以最好的方式还是在excel里编辑好,然后批量的导入到小程序数据库...
  • 前两篇我已经详细介绍了云数据库的部署以及数据库的增加和查询。今天我们就一起来探讨微信云数据库的数据删除。 修改操作和之前讲的那几种操作稍微有些不同。因为删除是根据在数据库里的id进行删除操作的。如下图 ...
  • 1.是否填写正确的环境ID 2.检查集合名称是否一致 3.检查集合的权限设置,更改为所有用户可读,仅创建者可读写 4.导入数据库注意 云开发的json文件中数据与数据之间不需要逗号隔开
  • 微信小程序云开发之云数据库入门介绍开发者可以使用云开发开发微信小程序、小游戏,无需搭建服务器,即可使用云端能力。其基础能力数据库,是一个JSON数据库,作用是无需自建数据库,就可以在微信小程序前端操作...
  • 小程序代码中无法直接修改他人创建的数据记录例如:数据库表中的_openid字段是自动生成的,哪个用户创建的记录这个openid就是用户的openid,云数据库的权限分配也是根据openid来进行的。解决方案:第一步:创建...
  • 【微信小程序云开发】解决云开发数据库调用产生的异步Promise数据问题和调用数据库存在20条上限的问题项目场景:代码描述:结语: 项目场景: 项目场景: 最近在开发一款查询类的微信小程序,由于使用的是小程序内部...
  • 一直以来在做微信小程序时都是自己配个服务器,然后写个接口供小程序调用做数据交互的,但是...步骤一、在”微信开发者工具”的左上方点击“云开发”后出现"云开发控制台"窗口,在该窗口中点击“数据库”,并在左侧的

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 196,867
精华内容 78,746
关键字:

云开发数据库