Skip to content

Files

Latest commit

d58b69a · Jun 2, 2020

History

History
1853 lines (1423 loc) · 46.6 KB

database.md

File metadata and controls

1853 lines (1423 loc) · 46.6 KB

API

基础概念

Collection

集合是一系列的文档集,通过 db.collection(name) 可以获取指定集合的引用,在集合上可以进行以下操作

类型 接口 说明
add 新增文档(触发请求)
计数 count 获取复合条件的文档条数
get 获取集合中的文档,如果有使用 where 语句定义查询条件,则会返回匹配结果集 (触发请求)
引用 doc 获取对该集合中指定 id 的文档的引用
查询条件 where 通过指定条件筛选出匹配的文档,可搭配查询指令(eq, gt, in, ...)使用
skip 跳过指定数量的文档,常用于分页,传入 offset
orderBy 排序方式
limit 返回的结果集(文档数量)的限制,有默认值和上限值
field 指定需要返回的字段

查询及更新指令用于在 where 中指定字段需满足的条件,指令可通过 db.command 对象取得。

Record / Document

文档是数据库集合中的一个存储单元,在云开发里是一个 json 对象。通过 db.collection(collectionName).doc(docId) 可以获取指定集合上指定 id 的文档的引用,在文档上可以进行以下操作

接口 说明
set
update
remove
get

Query Command

查询指令,应用于构建查询条件。以下指令皆挂载在 db.command

类型 接口 说明
比较运算 eq 字段 ==
neq 字段 !=
gt 字段 >
gte 字段 >=
lt 字段 <
lte 字段 <=
in 字段值在数组里
nin 字段值不在数组里
逻辑运算 and 表示需同时满足指定的所有条件
or 表示需同时满足指定条件中的至少一个

Update Command

更新指令,应用于构建更新操作。以下指令皆挂载在 db.command

类型 接口 说明
更新指令 set 设定字段等于指定值
inc 指示字段自增某个值
mul 指示字段自乘某个值
remove 删除某个字段
push 向数组尾部追加元素,支持传入单个元素或数组
pop 删除数组尾部元素
shift 删除数组头部元素。使用同 pop
unshift 向数组头部添加元素,支持传入单个元素或数组。使用同 push

获取数据库实例

说明:不需要参数,返回数据库的实例

// 初始化
const tcb = require('@cloudbase/node-sdk')
const app = tcb.init({
    env: 'xxx'
})
const db = app.database()

获取集合的引用

说明:接受一个 name 参数,指定需引用的集合名称

// 获取 `user` 集合的引用
const tcb = require('@cloudbase/node-sdk')
const app = tcb.init({
    env: 'xxx'
})

const db = app.database()

const collection = db.collection('user')

查询指令

eq

表示字段等于某个值。eq 指令接受一个字面量 (literal),可以是 number, boolean, string, object, array

比如筛选出所有自己发表的文章,除了用传对象的方式:

// 云函数环境下示例代码
const tcb = require('@cloudbase/node-sdk')
const app = tcb.init({
    env: 'xxx'
})
const db = app.database()

exports.main = async (event, context) => {
    const myOpenID = 'xxx'
    const res = await db
        .collection('articles')
        .where({
            _openid: myOpenID
        })
        .get()

    console.log(res.data) // 打印查询的文档数组

    // 用指令的方式
    const res1 = await db
        .collection('articles')
        .where({
            _openid: _.eq(myOpenID)
        })
        .get()

    console.log(res1.data) // 打印查询的文档数组
}

注意 eq 指令比对象的方式有更大的灵活性,可以用于表示字段等于某个对象的情况,比如:

// 云函数环境下示例代码
const tcb = require('@cloudbase/node-sdk')
const app = tcb.init({
    env: 'xxx'
})
const db = app.database()
const _ = db.command

exports.main = async (event, context) => {
    // 这种写法表示匹配 stat.publishYear == 2018 且 stat.language == 'zh-CN'
    const res = await db
        .collection('articles')
        .where({
            stat: {
                publishYear: 2018,
                language: 'zh-CN'
            }
        })
        .get()

    console.log(res.data) // 打印查询的文档数组

    // 这种写法表示 stat 对象等于 { publishYear: 2018, language: 'zh-CN' }
    const res1 = await db
        .collection('articles')
        .where({
            stat: _.eq({
                publishYear: 2018,
                language: 'zh-CN'
            })
        })
        .get()

    console.log(res1.data) // 打印查询的文档数组
}

neq

字段不等于。neq 指令接受一个字面量 (literal),可以是 number, boolean, string, object, array

如筛选出品牌不为 X 的计算机:

// 云函数环境下示例代码
const tcb = require('@cloudbase/node-sdk')
const app = tcb.init({
    env: 'xxx'
})
const db = app.database()
const _ = db.command

exports.main = async (event, context) => {
    const res = await db
        .collection('goods')
        .where({
            category: 'computer',
            type: {
                brand: _.neq('X')
            }
        })
        .get()

    console.log(res.data) // 打印查询的文档数组
}

gt

字段大于指定值。

如筛选出价格大于 2000 的计算机:

// 云函数环境下示例代码
const tcb = require('@cloudbase/node-sdk')
const app = tcb.init({
    env: 'xxx'
})
const db = app.database()
const _ = db.command

exports.main = async (event, context) => {
    const res = await db
        .collection('goods')
        .where({
            category: 'computer',
            price: _.gt(2000)
        })
        .get()

    console.log(res.data) // 打印查询的文档数组
}

gte

字段大于或等于指定值。

lt

字段小于指定值。

lte

字段小于或等于指定值。

in

字段值在给定的数组中。

筛选出内存为 8g 或 16g 的计算机商品:

// 云函数环境下示例代码
const tcb = require('@cloudbase/node-sdk')
const app = tcb.init({
    env: 'xxx'
})
const db = app.database()
const _ = db.command

exports.main = async (event, context) => {
    const res = await db
        .collection('goods')
        .where({
            category: 'computer',
            type: {
                memory: _.in([8, 16])
            }
        })
        .get()
    console.log(res.data) // 打印查询的文档数组
}

nin

字段值不在给定的数组中。

筛选出内存不是 8g 或 16g 的计算机商品:

// 云函数环境下示例代码
const tcb = require('@cloudbase/node-sdk')
const app = tcb.init({
    env: 'xxx'
})
const db = app.database()
const _ = db.command

exports.main = async (event, context) => {
    const res = await db
        .collection('goods')
        .where({
            category: 'computer',
            type: {
                memory: _.nin([8, 16])
            }
        })
        .get()
    console.log(res.data) // 打印查询的文档数组
}

and

表示需同时满足指定的两个或以上的条件。

如筛选出内存大于 4g 小于 32g 的计算机商品:

// 云函数环境下示例代码
const tcb = require('@cloudbase/node-sdk')
const app = tcb.init({
    env: 'xxx'
})
const db = app.database()
const _ = db.command

exports.main = async (event, context) => {
    // 流式写法
    const res = await db
        .collection('goods')
        .where({
            category: 'computer',
            type: {
                memory: _.gt(4).and(_.lt(32))
            }
        })
        .get()

    console.log(res.data) // 打印查询的文档数组

    // 前置写法
    const res1 = await db
        .collection('goods')
        .where({
            category: 'computer',
            type: {
                memory: _.and(_.gt(4), _.lt(32))
            }
        })
        .get()

    console.log(res1.data) // 打印查询的文档数组
}

or

表示需满足所有指定条件中的至少一个。如筛选出价格小于 4000 或在 6000-8000 之间的计算机:

// 云函数环境下示例代码
const tcb = require('@cloudbase/node-sdk')
const app = tcb.init({
    env: 'xxx'
})
const db = app.database()
const _ = db.command

exports.main = async (event, context) => {
    //流式写法:
    const res = await db
        .collection('goods')
        .where({
            category: 'computer',
            type: {
                price: _.lt(4000).or(_.gt(6000).and(_.lt(8000)))
            }
        })
        .get()
    console.log(res.data) // 打印查询的文档数组

    // 前置写法
    const res1 = await db
        .collection('goods')
        .where({
            category: 'computer',
            type: {
                price: _.or(_.lt(4000), _.and(_.gt(6000), _.lt(8000)))
            }
        })
        .get()

    console.log(res1.data) // 打印查询的文档数组

    // 如果要跨字段 “或” 操作:(如筛选出内存 8g 或 cpu 3.2 ghz 的计算机)
    const res2 = await db
        .collection('goods')
        .where(
            _.or(
                {
                    type: {
                        memory: _.gt(8)
                    }
                },
                {
                    type: {
                        cpu: 3.2
                    }
                }
            )
        )
        .get()

    console.log(res2.data) // 打印查询的文档数组
}

RegExp

根据正则表达式进行筛选

例如下面可以筛选出 version 字段开头是 "数字+s" 的文档,并且忽略大小写:

// 云函数环境下示例代码
const tcb = require('@cloudbase/node-sdk');
const app = tcb.init({
  env:'xxx'
})
const db = app.database()

exports.main = async (event, context) => {
  // 可以直接使用正则表达式
  const res = await db.collection('articles').where({
    version: /^\ds/i
  }).get()

  console.log(res.data) // 打印查询的文档数组

  // 或者
  const res1 = await db.collection('articles').where({
    version: new db.RegExp({
      regexp: '^\\ds'   // 正则表达式为 /^\ds/,转义后变成 '^\\ds'
      options: 'i'    // i表示忽略大小写
    })
  }).get()

  console.log(res1.data) // 打印查询的文档数组
}

更新指令

set

描述:用于设定字段等于指定值。这种方法相比传入纯 JS 对象的好处是能够指定字段等于一个对象。

示例代码:

// 云函数环境下示例代码
const tcb = require('@cloudbase/node-sdk')
const app = tcb.init({
    env: 'xxx'
})
const db = app.database()
const _ = db.command

exports.main = async (event, context) => {
    const res = await db
        .collection('photo')
        .doc('doc-id')
        .update({
            data: {
                style: _.set({
                    color: 'red',
                    size: 'large'
                })
            }
        })
    console.log(res.updated) // 打印更新成功的文档数量
}

inc

描述:用于指示字段自增某个值,这是个原子操作,使用这个操作指令而不是先读数据、再加、再写回的好处是:

备注:

  1. 原子性:多个用户同时写,对数据库来说都是将字段加一,不会有后来者覆写前者的情况
  2. 减少一次网络请求:不需先读再写

之后的 mul 指令同理。

示例代码:

// 云函数环境下示例代码
const tcb = require('@cloudbase/node-sdk')
const app = tcb.init({
    env: 'xxx'
})
const db = app.database()
const _ = db.command

exports.main = async (event, context) => {
    const res = await db
        .collection('user')
        .where({
            _openid: 'my-open-id'
        })
        .update({
            count: {
                favorites: _.inc(1)
            }
        })
    console.log(res.updated) // 打印更新成功的文档数量
}

mul

描述:用于指示字段自乘某个值。

remove

更新指令。用于表示删除某个字段。如某人删除了自己一条商品评价中的评分:

// 云函数环境下示例代码
const tcb = require('@cloudbase/node-sdk')
const app = tcb.init({
    env: 'xxx'
})
const db = app.database()
const _ = db.command

exports.main = async (event, context) => {
    const res = await db
        .collection('comments')
        .doc('comment-id')
        .update({
            rating: _.remove()
        })
    console.log(res.updated) // 打印更新成功的文档数量
}

push

向数组尾部追加元素,支持传入单个元素或数组

// 云函数环境下示例代码
const tcb = require('@cloudbase/node-sdk')
const app = tcb.init({
    env: 'xxx'
})
const db = app.database()
const _ = db.command

exports.main = async (event, context) => {
    const res = await db
        .collection('comments')
        .doc('comment-id')
        .update({
            // users: _.push('aaa')
            users: _.push(['aaa', 'bbb'])
        })
    console.log(res.updated) // 打印更新成功的文档数量
}

pop

删除数组尾部元素

// 云函数环境下示例代码
const tcb = require('@cloudbase/node-sdk')
const app = tcb.init({
    env: 'xxx'
})
const db = app.database()
const _ = db.command

exports.main = async (event, context) => {
    const res = await db
        .collection('comments')
        .doc('comment-id')
        .update({
            users: _.pop()
        })
    console.log(res.updated) // 打印更新成功的文档数量
}

unshift

向数组头部添加元素,支持传入单个元素或数组。使用同 push

shift

删除数组头部元素。使用同 pop

构建查询条件

支持 where()limit()skip()orderBy()get()update()field()count() 等操作。

只有当调用get()update()时才会真正发送请求。

where

描述:设置过滤条件。where 可接收对象作为参数,表示筛选出拥有和传入对象相同的 key-value 的文档。

输入参数: 无

比如筛选出所有类型为计算机的、内存为 8g 的商品:

// 云函数环境下示例代码
const tcb = require('@cloudbase/node-sdk')
const app = tcb.init({
    env: 'xxx'
})

const db = app.database()

exports.main = async (event, context) => {
    const res = await db
        .collection('goods')
        .where({
            category: 'computer',
            type: {
                memory: 8
            }
        })
        .get()
    console.log(res.data) // 打印查询的文档数组
}

如果要表达更复杂的查询,可使用高级查询指令,比如筛选出所有内存大于 8g 的计算机商品:

// 云函数环境下示例代码
const tcb = require('@cloudbase/node-sdk');
const app = tcb.init({
  env:'xxx'
})

const db = app.database();

const _ = db.command // 取指令

exports.main = async (event, context) => {
  const res = await db.collection('goods').where({
    category: 'computer',
    type: {
      memory: _.gt(8), // 表示大于 8
    }
  }).get()
  console.log(res.data) // 打印查询的文档数组

limit

描述:指定查询结果集数量上限

输入参数:

参数 类型 必填 说明
- Integer 限制展示的数值

使用示例

// 云函数环境下示例代码
const tcb = require('@cloudbase/node-sdk')
const app = tcb.init({
    env: 'xxx'
})
const db = app.database()
const collection = db.collection('user') // 例 操作 user 集合

exports.main = async (event, context) => {
    const res = await collection
        .where({})
        .limit(1)
        .get()
    console.log(res.data) // 打印查询的文档数组
}

skip

描述:指定查询返回结果时从指定序列后的结果开始返回,常用于分页 输入参数:

参数 类型 必填 说明
- Integer 限制展示的数值

示例代码

// 云函数环境下示例代码
const tcb = require('@cloudbase/node-sdk')
const app = tcb.init({
    env: 'xxx'
})
const db = app.database()
const collection = db.collection('user') // 例 操作 user 集合

exports.main = async (event, context) => {
    const res = await collection
        .where({})
        .skip(4)
        .get()
    console.log(res.data) // 打印查询的文档数组
}

field

描述:指定返回结果中文档需返回的字段

输入参数:

参数 类型 必填 说明
- Object 要过滤的字段,不返回传 false,返回传 true

示例代码

// 云函数环境下示例代码
const tcb = require('@cloudbase/node-sdk')
const app = tcb.init({
    env: 'xxx'
})
const db = app.database()
const collection = db.collection('user') // 例 操作 user 集合

exports.main = async (event, context) => {
    const res = await collection
        .where({})
        .field({ age: true })
        .get()
    console.log(res.data) // 打印查询的文档数组
}

备注:field 方法接受一个必填对象用于指定需返回的字段,对象的各个 key 表示要返回或不要返回的字段,value 传入 true|false(或 1|0)表示要返回还是不要返回。

orderBy

描述:指定查询排序条件

输入参数:

参数 类型 必填 说明
field String 排序的字段
orderType String 排序的顺序,升序(asc) 或 降序(desc)

备注:方法接受一个必填字符串参数 fieldName 用于定义需要排序的字段,一个字符串参数 order 定义排序顺序。order 只能取 asc 或 desc。

如果需要对嵌套字段排序,需要用 "点表示法" 连接嵌套字段,比如 style.color 表示字段 style 里的嵌套字段 color。

同时也支持按多个字段排序,多次调用 orderBy 即可,多字段排序时的顺序会按照 orderBy 调用顺序先后对多个字段排序

示例代码

// 云函数环境下示例代码
const tcb = require('@cloudbase/node-sdk')
const app = tcb.init({
    env: 'xxx'
})
const db = app.database()
const collection = db.collection('user') // 例 操作 user 集合

exports.main = async (event, context) => {
    const res = await collection
        .where({})
        .orderBy('name', 'asc')
        .get()
    console.log(res.data) // 打印查询的文档数组
}

options

描述:数据库接口配置

输入参数:

参数 类型 必填 说明
timeout Number SDK 请求超时时间设置, 默认 15000ms
multiple Boolean 是否仅操作单个文档,update/delete 方法可用

示例代码

// 云函数环境下示例代码
const tcb = require('@cloudbase/node-sdk')
const app = tcb.init({
    env: 'xxx'
})
const db = app.database()
const collection = db.collection('user') // 例 操作 user 集合

exports.main = async (event, context) => {
    // 更新单文档
    const updateRes = await collection
        .where({ name: 'luke' })
        .options({ multiple: false })
        .update({
            name: 'lake'
        })

    console.log(res.updated === 1) // 更新文档数为1

    // 删除单文档
    const deleteRes = await collection
        .where({ name: 'luke' })
        .options({ multiple: false })
        .remove()

    console.log(res.deleted === 1) // 删除文档数为1

    // 设置SDK单接口请求超时
    const getRes = await collection
        .where({ name: 'luke' })
        .options({ timeout: 10000 })
        .get()
    console.log(getRes)
}

createCollection

1. 接口描述

接口功能:新增集合

接口声明:createCollection(collName): Promise<Object>

2. 输入参数

参数 类型 必填 说明
- String 集合名

3. 返回结果

字段 类型 必填 说明
requestId String 请求 ID
message String 接口报错时的错误信息
code String 接口报错时的错误码

4. 示例代码

// 云函数环境下示例代码
const tcb = require('@cloudbase/node-sdk')
const app = tcb.init({
    env: 'xxx'
})

const db = app.database()

exports.main = async (event, context) => {
    // 创建集合名为coll-name的集合
    const res = await db.createCollection('coll-name')

    if (!res.code) {
        // 创建成功
    }
}

add

1. 接口描述

接口功能:插入一条文档或文档数组

接口声明:collection.add(object: Array<Object> | Object): Promise<Object>

备注:set 方法也可以用来新增文档,请参看文档更新部分 set 方法

2. 输入参数

参数 类型 必填 说明
- Array<Object> or Object 可支持批量插入或插入单个文档,例 [{_id: '10001', 'name': 'Ben'}, {_id: '10002', 'name': 'Booker'}] 或 {_id: '10001', 'name': 'Ben'}, _id 非必填

3. 返回结果

字段 类型 必填 说明
code String 状态码,操作成功则不返回
message String 错误描述,操作成功不返回
requestId String 请求 ID
id String 文档 ID,插入单文档成功则返回
ids Array<String> 文档 ID,批量插入文档成功则返回

4. 示例代码

// 云函数环境下示例代码
const tcb = require('@cloudbase/node-sdk')
const app = tcb.init({
    env: 'xxx'
})

const db = app.database()
const collection = db.collection('user') // 例 操作 user 集合

exports.main = async (event, context) => {
    // 创建集合名为coll-name的集合
    const res = await collection.add({
        name: 'Ben'
    })

    console.log(res.id) //打印新增的文档ID

    const batchRes = await collection.add([{ name: 'luke' }, { name: 'jimmy' }])
    console.log(batchRes.ids)
}

get

1. 接口描述

接口功能:获取数据库查询结果

接口声明:get(): Promise<Object>

注:get()如不指定 limit 则默认取前 100 条数据,且最大取前 100 条数据。

2. 输入参数

3. 返回结果

字段 类型 必填 说明
code string 状态码,操作成功则不返回
message string 错误描述
data Object 操作成功返回查询结果
requestId string 请求序列号,用于错误排查

4. 示例代码

// 云函数环境下示例代码
const tcb = require('@cloudbase/node-sdk')
const app = tcb.init({
    env: 'xxx'
})
const db = app.database()

exports.main = async (event, context) => {
    const res = await db
        .collection('goods')
        .where({
            category: 'computer',
            type: {
                memory: 8
            }
        })
        .count()
    console.log(res.data) // 打印查询的文档数组
}

count

1. 接口描述

接口功能:获取数据库查询结果

接口声明:cout(): Promise<Object>

2. 输入参数

3. 返回结果

字段 类型 必填 说明
code string 状态码,操作成功则不返回
message string 错误描述
total integer 计数结果
requestId string 请求序列号,用于错误排查

4. 示例代码

// 云函数环境下示例代码
const tcb = require('@cloudbase/node-sdk')
const app = tcb.init({
    env: 'xxx'
})
const db = app.database()

exports.main = async (event, context) => {
    const res = await db
        .collection('goods')
        .where({
            category: 'computer',
            type: {
                memory: 8
            }
        })
        .count()
    console.log(res.total) // 打印查询的文档数量
}

remove

1. 接口描述

接口功能:删除一条文档

接口声明:remove(): Promise<Object>

2. 输入参数

3. 返回结果

字段 类型 必填 说明
code string 状态码,操作成功则不返回
message string 错误描述
deleted integer 删除的文档数量
requestId string 请求序列号,用于错误排查

4. 示例代码

方式 1. 通过 � 指定文档 ID 删除

collection.doc(_id).remove()

// 云函数环境下示例代码
const tcb = require('@cloudbase/node-sdk')
const app = tcb.init({
    env: 'xxx'
})
const db = app.database()

exports.main = async (event, context) => {
    const res = await db
        .collection('articles')
        .doc('xxx')
        .remove()

    console.log(res.deleted) // 打印删除的文档数量
}

方式 2. 条件查找文档然后直接批量删除

// 云函数环境下示例代码
const tcb = require('@cloudbase/node-sdk')
const app = tcb.init({
    env: 'xxx'
})
const db = app.database()

exports.main = async (event, context) => {
    // 删除字段a的值大于2的文档
    const res = await db
        .collection('articles')
        .where({
            a: _.gt(2)
        })
        .remove()

    console.log(res.deleted) // 打印删除的文档数量
}

update / set

1. 接口描述

接口功能:更新文档

接口声明:

update(object: <Object>): Promise<Object>

set(object: <Object>): Promise<Object>

备注:update 和 set 都可以用来更新文档,区别是 set 方法在要更新的文档不存在时新增一个文档;而 update 方法什么也不会做,返回 updated 为 0

2. 输入参数

字段 类型 必填 说明
- <Object> 替换文档的定义

3. 返回结果

字段 类型 必填 说明
code string 状态码,操作成功则不返回
message string 错误描述
updated integer 影响的文档数量
upsertedId string 插入的文档的 id
requestId string 请求序列号,用于错误排查

4. 示例代码

更新指定文档

// 云函数环境下示例代码
const tcb = require('@cloudbase/node-sdk')
const app = tcb.init({
    env: 'xxx'
})
const db = app.database()

exports.main = async (event, context) => {
    // 更新单文档
    const res = await db
        .collection('articles')
        .doc('doc-id')
        .update({
            name: 'Hey'
        })

    console.log(res.updated) // 打印更新成功的文档数量

    // 批量更新文档
    const res1 = await db
        .collection('articles')
        .where({ name: _.eq('hey') })
        .update({
            age: 18
        })

    console.log(res1.updated) // 打印更新成功的文档数量
}

更新文档,如果不存在则创建

// 云函数环境下示例代码
const tcb = require('@cloudbase/node-sdk')
const app = tcb.init({
    env: 'xxx'
})
const db = app.database()

exports.main = async (event, context) => {
    // 更新单文档
    const res = await db
        .collection('articles')
        .doc('doc-id')
        .set({
            name: 'Hey'
        })
    console.log(res.upsertedId) // 打印插入的文档的id
}

GEO 地理位置

注意:如果需要对类型为地理位置的字段进行搜索,一定要建立地理位置索引

GEO 数据类型

Point

用于表示地理位置点,用经纬度唯一标记一个点,这是一个特殊的数据存储类型。

签名:Point(longitude: number, latitude: number)

示例:

new db.Geo.Point(longitude, latitude)

LineString

用于表示地理路径,是由两个或者更多的 Point 组成的线段。

签名:LineString(points: Point[])

示例:

new db.Geo.LineString([
    new db.Geo.Point(lngA, latA),
    new db.Geo.Point(lngB, latB)
    // ...
])

Polygon

用于表示地理上的一个多边形(有洞或无洞均可),它是由一个或多个闭环 LineString 组成的几何图形。

由一个环组成的 Polygon 是没有洞的多边形,由多个环组成的是有洞的多边形。对由多个环(LineString)组成的多边形(Polygon),第一个环是外环,所有其他环是内环(洞)。

签名:Polygon(lines: LineString[])

示例:

new db.Geo.Polygon([
  new db.Geo.LineString(...),
  new db.Geo.LineString(...),
  // ...
])

MultiPoint

用于表示多个点 Point 的集合。

签名:MultiPoint(points: Point[])

示例:

new db.Geo.MultiPoint([
    new db.Geo.Point(lngA, latA),
    new db.Geo.Point(lngB, latB)
    // ...
])

MultiLineString

用于表示多个地理路径 LineString 的集合。

签名:MultiLineString(lines: LineString[])

示例:

new db.Geo.MultiLineString([
  new db.Geo.LineString(...),
  new db.Geo.LineString(...),
  // ...
])

MultiPolygon

用于表示多个地理多边形 Polygon 的集合。

签名:MultiPolygon(polygons: Polygon[])

示例:

new db.Geo.MultiPolygon([
  new db.Geo.Polygon(...),
  new db.Geo.Polygon(...),
  // ...
])

GEO 操作符

geoNear

按从近到远的顺序,找出字段值在给定点的附近的文档。

签名:

db.command.geoNear(options: IOptions)

interface IOptions {
  geometry: Point // 点的地理位置
  maxDistance?: number // 选填,最大距离,米为单位
  minDistance?: number // 选填,最小距离,米为单位
}

示例:

// 云函数环境下示例代码
const tcb = require('@cloudbase/node-sdk')
const app = tcb.init({
    env: 'xxx'
})
const db = app.database()
const _ = db.command

exports.main = async (event, context) => {
    const res = await db
        .collection('user')
        .where({
            location: db.command.geoNear({
                geometry: new db.Geo.Point(lngA, latA),
                maxDistance: 1000,
                minDistance: 0
            })
        })
        .get()
    console.log(res.data) // 打印查询的文档数组
}

geoWithin

找出字段值在指定 Polygon / MultiPolygon 内的文档,无排序

签名:

db.command.geoWithin(IOptions)

interface IOptions {
    geometry: Polygon | MultiPolygon; // 地理位置
}

示例:

// 云函数环境下示例代码
const tcb = require('@cloudbase/node-sdk')
const app = tcb.init({
    env: 'xxx'
})
const db = app.database()
const _ = db.command

exports.main = async (event, context) => {
    // 一个闭合的区域
    const area = new Polygon([
        new LineString([
            new Point(lngA, latA),
            new Point(lngB, latB),
            new Point(lngC, latC),
            new Point(lngA, latA)
        ])
    ])

    // 搜索 location 字段在这个区域中的 user
    const res = await db
        .collection('user')
        .where({
            location: db.command.geoWithin({
                geometry: area
            })
        })
        .get()
    console.log(res.data) // 打印查询的文档数组
}

geoIntersects

找出字段值和给定的地理位置图形相交的文档

签名:

db.command.geoIntersects(IOptions)

interface IOptions {
    geometry: Point | LineString | MultiPoint | MultiLineString | Polygon | MultiPolygon; // 地理位置
}

示例:

// 云函数环境下示例代码
const tcb = require('@cloudbase/node-sdk')
const app = tcb.init({
    env: 'xxx'
})
const db = app.database()
const _ = db.command

exports.main = async (event, context) => {
    // 一条路径
    const line = new LineString([new Point(lngA, latA), new Point(lngB, latB)])

    // 搜索 location 与这条路径相交的 user
    const res = await db
        .collection('user')
        .where({
            location: db.command.geoIntersects({
                geometry: line
            })
        })
        .get()
    console.log(res.data) // 打印查询的文档数组
}

时间 Date

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

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

//服务端当前时间
new db.serverDate()
//服务端当前时间加1S
new db.serverDate({
    offset: 1000
})

数据库事务

startTransaction

1. 接口描述

接口功能:发起事务

接口声明:startTransaction(): Promise<Object>

2. 输入参数

3. 返回结果

参数 类型 必填 说明
_id string 成功则返回事务 id
code string 状态码,操作成功则不返回
message string 错误描述

4. 示例代码

// 云函数环境下示例代码
const tcb = require('@cloudbase/node-sdk')
const app = tcb.init({
    env: 'xxx'
})
const db = app.database()

exports.main = async (event, context) => {
    const transaction = await db.startTransaction()
    console.log(transaction._id) // 打印事务id
}

commit

1. 接口描述

接口功能:提交事务

接口声明:commit(): Promise<Object>

2. 输入参数

3. 返回结果

字段 类型 必填 说明
requestId string 请求 id
code string 状态码,操作成功则不返回
message string 错误描述, 操作成功则不返回

4. 示例代码

// 云函数环境下示例代码
const tcb = require('@cloudbase/node-sdk')
const app = tcb.init({
    env: 'xxx'
})
const db = app.database()

exports.main = async (event, context) => {
    const transaction = await db.startTransaction()
    await transaction.commit()
}

get

1. 接口描述

接口功能:事务查询文档

接口声明:get(): Promise<Object>

2. 输入参数

3. 返回结果

参数 类型 必填 说明
data <Array>.Object 操作成功,返回文档对象数组
requestId string 请求 id
code string 状态码,操作成功则不返回
message string 错误描述, 操作成功则不返回

4. 示例代码

// 云函数环境下示例代码
const tcb = require('@cloudbase/node-sdk')
const app = tcb.init({
    env: 'xxx'
})
const db = app.database()

exports.main = async (event, context) => {
    /**
     * 事务操作支持两种写法,写法一如下,1. 调用startTransaction发起事务 2. 事务操作 3.调用commitTransactio提交事务
     *
     *
     */
    const transaction = await db.startTransaction()
    const doc = await transaction
        .collection(collectionName)
        .doc('docId')
        .get()
    console.log(doc.data) // 打印查询的文档
    await transaction.commit()

    /**
     * 写法二,runTransaction(callback(transaction)), 支持用户传入回调,回调参数为transaction
     *
     *
     */
    await db.runTransaction(async function(transaction) {
        const doc = await transaction
            .collection(collectionName)
            .doc('docId')
            .get()
        console.log(doc.data) // 打印查询的文档
    })
}

add

1. 接口描述

接口功能:事务插入文档

接口声明:add(data): Promise<Object>

2. 输入参数

参数 类型 必填 说明
- Object 例 {_id: '10001', 'name': 'Ben'} _id 非必填

3. 返回结果

参数 类型 必填 说明
requestId string 请求 id
code string 状态码,操作成功则不返回
message string 错误描述, 操作成功则不返回
id string 插入数据的 docId
inserted number 插入成功的条数
ok number 插入状态 1 表示成功

4. 示例代码

// 云函数环境下示例代码
const tcb = require('@cloudbase/node-sdk')
const app = tcb.init({
    env: 'xxx'
})
const db = app.database()

exports.main = async (event, context) => {
    // 云函数环境下,下面代码放置入口函数体内
    const transaction = await db.startTransaction()
    const res = await transaction
        .collection(collectionName)
        .add({ category: 'Web', tags: ['JavaScript', 'C#'], date })
    console.log(res.id) // 打印添加的docId
    await transaction.commit()
}

update / set

1. 接口描述

接口功能:事务更新文档

接口声明:

update(data): Promise<Object>

set(object: Object): Promise<Object>

备注:update 和 set 都可以用来更新文档,区别是 set 方法在要更新的文档不存在时新增一个文档;而 update 方法什么也不会做,返回 updated 为 0

2. 输入参数

参数 类型 必填 说明
- Object 要更新的字段对象

3. 返回结果

参数 类型 必填 说明
updated number 更新成功的条数
upserted number 插入成功的条数
requestId string 请求 id
code string 状态码,操作成功则不返回
message string 错误描述, 操作成功则不返回

4. 示例代码

// 云函数环境下示例代码
const tcb = require('@cloudbase/node-sdk')
const app = tcb.init({
    env: 'xxx'
})
const db = app.database()

exports.main = async (event, context) => {
    const transaction = await db.startTransaction()
    // update
    const updateResult = await transaction
        .collection(collectionName)
        .doc('docId')
        .update({
            category: 'Node.js',
            date
        })

    console.log(updateResult.updated) // 更新的条数

    // set
    const setResult = await transaction
        .collection(collectionName)
        .doc('docId')
        .set({
            category: 'Node.js',
            date
        })

    console.log(setResult.updated, setResult.upserted)
    await transaction.commit()
}

delete

1. 接口描述

接口功能:事务删除文档

接口声明:delete(): Promise<Object>

2. 输入参数

3. 返回结果

字段 类型 必填 说明
deleted number 删除成功的条数
requestId string 请求 id
code string 状态码,操作成功则不返回
message string 错误描述, 操作成功则不返回

4. 示例代码

// 云函数环境下示例代码
const tcb = require('@cloudbase/node-sdk')
const app = tcb.init({
    env: 'xxx'
})
const db = app.database()

exports.main = async (event, context) => {
    // deletaDocument
    const transaction = await db.startTransaction()
    const deleteResult = await transaction
        .collection(collectionName)
        .doc('docId')
        .delete()
    console.log(deleteResult.deleted) // 删除成功的条数
    await transaction.commit()
}

rollback

1. 接口描述

接口功能:事务回滚

接口声明:rollback(): Promise<Object>

2. 输入参数

3. 返回结果

字段 类型 必填 说明
requestId string 请求 id

4. 示例代码

// 云函数环境下示例代码
const tcb = require('@cloudbase/node-sdk')
const app = tcb.init({
    env: 'xxx'
})
const db = app.database()

exports.main = async (event, context) => {
    // 云函数环境下,下面代码放置入口函数体内
    const transaction = await db.startTransaction()
    const doc = await transaction
        .collection(collectionName)
        .doc('docId')
        .get()
    console.log(doc.data)
    await transaction.rollback()
    await transaction.commit()
}

runTransaction 使用说明

  1. 支持自定义返回 (正常 return 或 throw error)
// 云函数环境下示例代码
const tcb = require('@cloudbase/node-sdk')
const app = tcb.init({
    env: 'xxx'
})
const db = app.database()

exports.main = async (event, context) => {
    const result = await db.runTransaction(async function(transaction) {
        const doc = await transaction
            .collection(collectionName)
            .doc('1')
            .get()
        console.log(doc.data)
        return 'luke'
    })
}

// result === 'luke'
// 云函数环境下示例代码
const tcb = require('@cloudbase/node-sdk')
const app = tcb.init({
    env: 'xxx'
})
const db = app.database()

exports.main = async (event, context) => {
    try {
        await db.runTransaction(async transaction => {
            const doc = await transaction
                .collection(collectionName)
                .doc('1')
                .get()
            console.log(doc.data)
            // mock 事务冲突
            throw {
                code: 'DATABASE_TRANSACTION_CONFLICT',
                message:
                    '[ResourceUnavailable.TransactionConflict] Transaction is conflict, maybe resource operated by others. Please check your request, but if the problem persists, contact us.'
            }
        })
    } catch (e) {
        // e.code === 'DATABASE_TRANSACTION_CONFLICT'
    }
}
  1. rollback 使用
// 云函数环境下示例代码
const tcb = require('@cloudbase/node-sdk')
const app = tcb.init({
    env: 'xxx'
})
const db = app.database()

exports.main = async (event, context) => {
    try {
        await db.runTransaction(async function(transaction) {
            const doc = await transaction
                .collection(collectionName)
                .doc('1')
                .get()
            console.log(doc.data)
            await transaction.rollback('luke')
        })
    } catch (err) {
        // err === 'luke'
    }

    try {
        await db.runTransaction(async function(transaction) {
            const doc = await transaction
                .collection(collectionName)
                .doc('1')
                .get()
            console.log(doc.data)
            await transaction.rollback()
        })
    } catch (err) {
        // assert(err.requestId)
        console.log(err.requestId) // 默认rollback返回回滚的requestId
    }
}