uniCloud
提供了一个 JSON 格式的文档型数据库,数据库中的每条记录都是一个 JSON 格式的对象。一个数据库能够有多个集合(至关于关系型数据中的表),集合可看作一个 JSON 数组,数组中的每一个对象就是一条记录,记录的格式是 JSON 对象。javascript
关系型数据库和 JSON 文档型数据库的概念对应关系以下表:java
关系型 | JSON 文档型 |
---|---|
数据库 database | 数据库 database |
表 table | 集合 collection |
行 row | 记录 record / doc |
列 column | 字段 field |
uniCloud
云函数中可访问云数据库。正则表达式
鉴于安全问题,暂不支持客户端直接访问数据库。sql
const db = uniCloud.database();
复制代码
// 获取 `user` 集合的引用const collection = db.collection('user');
复制代码
经过 db.collection(name)
能够获取指定集合的引用,在集合上能够进行如下操做mongodb
类型 | 接口 | 说明 |
---|---|---|
写 | add | 新增记录(触发请求) |
计数 | count | 获取符合条件的记录条数 |
读 | get | 获取集合中的记录,若是有使用 where 语句定义查询条件,则会返回匹配结果集 (触发请求) |
引用 | doc | 获取对该集合中指定 id 的记录的引用 |
查询条件 | where | 经过指定条件筛选出匹配的记录,可搭配查询指令(eq, gt, in, …)使用 |
skip | 跳过指定数量的文档,经常使用于分页,传入 offset | |
orderBy | 排序方式 | |
limit | 返回的结果集(文档数量)的限制,有默认值和上限值 | |
field | 指定须要返回的字段 |
查询及更新指令用于在 where
中指定字段需知足的条件,指令可经过 db.command
对象取得。数据库
经过 db.collection(collectionName).doc(docId)
能够获取指定集合上指定 id 的记录的引用,在记录上能够进行如下操做json
接口 | 说明 | |
---|---|---|
写 | set | 覆写记录 |
update | 局部更新记录(触发请求) | |
remove | 删除记录(触发请求) | |
读 | get | 获取记录(触发请求) |
如下指令挂载在 db.command
下数组
类型 | 接口 | 说明 |
---|---|---|
比较运算 | eq | 字段等于 == |
neq | 字段不等于 != | |
gt | 字段大于 > | |
gte | 字段大于等于 >= | |
lt | 字段小于 < | |
lte | 字段小于等于 <= | |
in | 字段值在数组里 | |
nin | 字段值不在数组里 | |
逻辑运算 | and | 表示需同时知足指定的全部条件 |
or | 表示需同时知足指定条件中的至少一个 |
若是你熟悉SQL,可查询mongodb与sql语句对照表进行学习。promise
如下指令挂载在 db.command
下安全
类型 | 接口 | 说明 |
---|---|---|
字段 | set | 设置字段值 |
remove | 删除字段 | |
inc | 加一个数值,原子自增 | |
mul | 乘一个数值,原子自乘 | |
push | 数组类型字段追加尾元素,支持数组 | |
pop | 数组类型字段删除尾元素,支持数组 | |
shift | 数组类型字段删除头元素,支持数组 | |
unshift | 数组类型字段追加头元素,支持数组 |
数据库提供如下几种数据类型:
注意
如下对几个特殊的数据类型作个补充说明
Date 类型用于表示时间,精确到毫秒,能够用 JavaScript 内置 Date 对象建立。须要特别注意的是,用此方法建立的时间是客户端时间,不是服务端时间。若是须要使用服务端时间,应该用 API 中提供的 serverDate 对象来建立一个服务端当前时间的标记,当使用了 serverDate 对象的请求抵达服务端处理时,该字段会被转换成服务端当前的时间,更棒的是,咱们在构造 serverDate 对象时还可经过传入一个有 offset 字段的对象来标记一个与当前服务端时间偏移 offset 毫秒的时间,这样咱们就能够达到好比以下效果:指定一个字段为服务端时间日后一个小时。
那么当咱们须要使用客户端时间时,存放 Date 对象和存放毫秒数是不是同样的效果呢?不是的,咱们的数据库有针对日期类型的优化,建议你们使用时都用 Date 或 serverDate 构造时间对象。
//服务端当前时间 new db.serverDate()
//服务端当前时间加1S new db.serverDate({ offset: 1000 })
复制代码
Tips
2020-02-10T04:59:05.579Z
形式,便可以在云函数中使用new Date().toISOString()
获得。阿里云暂不支持地理位置类型
Null 至关于一个占位符,表示一个字段存在可是值为空。
方法1: collection.add(data)
示例:
参数 | 类型 | 必填 | 说明 |
---|---|---|---|
data | object | array | 是 | {_id: '10001', 'name': 'Ben'} _id 非必填 |
// 单条插入数据
collection.add({
name: 'Ben'
}).then((res) => {
});
// 批量插入数据
collection.add([{
name: 'Alex'
},{
name: 'Ben'
},{
name: 'John'
}]).then((res) => {
// res.inserted // 插入成功条数
// res.result // 阿里云特有,批量插入返回的全部记录 id
// res.failIndexes // 腾讯云特有,插入失败的记录的下标
});
复制代码
Tips
方法2: collection.doc().set(data)
也可经过 set
方法新增一个文档,需先取得文档引用再调用 set
方法。若是文档不存在,set
方法会建立一个新文档。
collection.doc().set({ name: "Hey"});
复制代码
支持 where()
、limit()
、skip()
、orderBy()
、get()
、update()
、field()
、count()
等操做。
只有当调用get()
update()
时才会真正发送请求。注:默认取前100条数据,最大取前100条数据。
collection.where()参数
设置过滤条件where 可接收对象做为参数,表示筛选出拥有和传入对象相同的 key-value 的文档。好比筛选出全部类型为计算机的、内存为 8g 的商品:
db.collection('goods').where({
category: 'computer',
type: {
memory: 8,
}
})
复制代码
若是要表达更复杂的查询,可以使用高级查询指令,好比筛选出全部内存大于 8g 的计算机商品:
const dbCmd = db.command // 取指令
db.collection('goods').where({
category: 'computer',
type: {
memory: dbCmd.gt(8), // 表示大于 8
}
})
复制代码
where
可使用正则表达式来查询文档,好比一下示例查询全部name
字段以ABC开头的用户
db.collection('user').where({
name: new RegExp('^ABC')
})
复制代码
collection.count()
参数
db.collection('goods').where({
category: 'computer',
type: {
memory: 8,
}
}).count().then(function(res) {
})
复制代码
响应参数
字段 | 类型 | 必填 | 说明 |
---|---|---|---|
code | string | 否 | 状态码,操做成功则不返回 |
message | string | 否 | 错误描述 |
total | Integer | 否 | 计数结果 |
requestId | string | 否 | 请求序列号,用于错误排查 |
collection.limit()
参数说明
参数 | 类型 | 必填 | 说明 |
---|---|---|---|
value | Integer | 是 | 限制展现的数值 |
使用示例
collection.limit(1).get().then(function(res) {
});
复制代码
collection.skip()
参数说明
参数 | 类型 | 必填 | 说明 |
---|---|---|---|
value | Integer | 是 | 跳过展现的数据 |
使用示例
collection.skip(4).get().then(function(res) {
});
复制代码
collection.orderBy()
参数说明
参数 | 类型 | 必填 | 说明 |
---|---|---|---|
field | string | 是 | 排序的字段 |
orderType | string | 是 | 排序的顺序,升序(asc) 或 降序(desc) |
使用示例
collection.orderBy("name", "asc").get().then(function(res) {
});
复制代码
collection.field()
参数说明
参数 | 类型 | 必填 | 说明 |
---|---|---|---|
- | object | 是 | 要过滤的字段,不返回传false,返回传true |
使用示例
collection.field({ 'age': true })
复制代码
备注:只能指定要返回的字段或者不要返回的字段。即{'a': true, 'b': false}是一种错误的参数格式
表示字段等于某个值。eq
指令接受一个字面量 (literal),能够是 number
, boolean
, string
, object
, array
。
好比筛选出全部本身发表的文章,除了用传对象的方式:
const myOpenID = "xxx"
db.collection('articles').where({
_openid: myOpenID
})
复制代码
还能够用指令:
const dbCmd = db.command
const myOpenID = "xxx"
db.collection('articles').where({
_openid: dbCmd.eq(openid)
})
复制代码
注意 eq
指令比对象的方式有更大的灵活性,能够用于表示字段等于某个对象的状况,好比:
// 这种写法表示匹配 stat.publishYear == 2018 且 stat.language == 'zh-CN'
db.collection('articles').where({
stat: {
publishYear: 2018,
language: 'zh-CN'
}
})
// 这种写法表示 stat 对象等于 { publishYear: 2018, language: 'zh-CN' }
const dbCmd = db.command
db.collection('articles').where({
stat: dbCmd.eq({
publishYear: 2018,
language: 'zh-CN'
})
})
复制代码
字段不等于。neq
指令接受一个字面量 (literal),能够是 number
, boolean
, string
, object
, array
。
如筛选出品牌不为 X 的计算机:
const dbCmd = db.command
db.collection('goods').where({
category: 'computer',
type: {
brand: dbCmd.neq('X')
},
})
复制代码
字段大于指定值。
如筛选出价格大于 2000 的计算机:
const dbCmd = db.command
db.collection('goods').where({
category: 'computer',
price: dbCmd.gt(2000)
})
复制代码
字段大于或等于指定值。
字段小于指定值。
字段小于或等于指定值。
字段值在给定的数组中。
筛选出内存为 8g 或 16g 的计算机商品:
const dbCmd = db.command
db.collection('goods').where({
category: 'computer',
type: {
memory: dbCmd.in([8, 16])
}
})
复制代码
字段值不在给定的数组中。
筛选出内存不是 8g 或 16g 的计算机商品:
const dbCmd = db.command
db.collection('goods').where({
category: 'computer',
type: {
memory: dbCmd.nin([8, 16])
}
})
复制代码
表示需同时知足指定的两个或以上的条件。
如筛选出内存大于 4g 小于 32g 的计算机商品:
流式写法:
const dbCmd = db.command
db.collection('goods').where({
category: 'computer',
type: {
memory: dbCmd.gt(4).and(dbCmd.lt(32))
}
})
复制代码
前置写法:
const dbCmd = db.command
db.collection('goods').where({
category: 'computer',
type: {
memory: dbCmd.and(dbCmd.gt(4), dbCmd.lt(32))
}
})
复制代码
表示需知足全部指定条件中的至少一个。如筛选出价格小于 4000 或在 6000-8000 之间的计算机:
流式写法:
const dbCmd = db.command
db.collection('goods').where({
category: 'computer',
type: {
price:dbCmd.lt(4000).or(dbCmd.gt(6000).and(dbCmd.lt(8000)))
}
})
复制代码
前置写法:
const dbCmd = db.command
db.collection('goods').where({
category: 'computer',
type: {
price: dbCmd.or(dbCmd.lt(4000), dbCmd.and(dbCmd.gt(6000), dbCmd.lt(8000)))
}
})
复制代码
若是要跨字段 “或” 操做:(如筛选出内存 8g 或 cpu 3.2 ghz 的计算机)
const dbCmd = db.command
db.collection('goods').where(dbCmd.or(
{
type: {
memory: dbCmd.gt(8)
}
},
{
type: {
cpu: 3.2
}
}
))
复制代码
根据正则表达式进行筛选
例以下面能够筛选出 version
字段开头是 "数字+s" 的记录,而且忽略大小写:
// 能够直接使用正则表达式
db.collection('articles').where({
version: /^\ds/i
})
// 或者
db.collection('articles').where({
version: new db.RegExp({
regex: '^\\ds' // 正则表达式为 /^\ds/,转义后变成 '^\\ds'
options: 'i' // i表示忽略大小写
})
})
复制代码
方式1 经过指定文档ID删除
collection.doc(_id).remove()
// 清理所有数据
collection.get()
.then((res) => {
const promiseList = res.data.map(document => {
return collection.doc(document.id).remove();
});
Promise.all(promiseList);
})
.catch((e) => {
});
复制代码
方式2 条件查找文档而后直接批量删除
collection.where().remove()
// 删除字段a的值大于2的文档
const dbCmd = db.command
collection.where({
a: dbCmd.gt(2)
}).remove().then(function(res) {
})
复制代码
collection.doc().update()
collection.doc('doc-id').update({
name: "Hey",
count: {
fav: 1
}
});
复制代码
// 更新前
{
"_id": "xxx",
"name": "Hello",
"count": {
"fav": 0,
"follow": 0
}
}
// 更新后
{
"_id": "xxx",
"name": "Hey",
"count": {
"fav": 1,
"follow": 0
}
}
复制代码
更新数组时,已数组下标做为key便可,好比如下示例将数组arr内下标为1的值修改成 uniCloud
collection.doc('doc-id').update({
arr: {
1: "uniCloud"
}
})
复制代码
// 更新前
{
"arr": ["hello", "world"]
}
// 更新后
{
"arr": ["hello", "uniCloud"]
}
复制代码
collection.doc().set()
注意:
update
表现不一样,好比如下示例执行set
以后follow
字段会被删除collection.doc('doc-id').set({
name: "Hey",
count: {
fav: 1
}
}).then(function(res) {
});
复制代码
// 更新前
{
"_id": "xxx",
"name": "Hello",
"count": {
"fav": 0,
"follow": 0
}
}
// 更新后
{
"_id": "xxx",
"name": "Hey",
"count": {
"fav": 1
}
}
复制代码
collection.update()
const dbCmd = db.command
collection.where({name: dbCmd.eq('hey')}).update({
age: 18,
}).then(function(res) {
});
复制代码
更新指令。用于设定字段等于指定值。这种方法相比传入纯 JS 对象的好处是可以指定字段等于一个对象:
const dbCmd = db.command
db.collection('photo').doc('doc-id').update({
count: dbCmd.set({
fav: 1,
follow: 1
})
}).then(function(res) {
})
复制代码
// 更新前
{
"_id": "xxx",
"name": "Hello",
"count": {
"fav": 0,
"follow": 0
}
}
// 更新后
{
"_id": "xxx",
"name": "Hello",
"count": {
"fav": 1,
"follow": 1
}
}
复制代码
更新指令。用于指示字段自增某个值,这是个原子操做,使用这个操做指令而不是先读数据、再加、再写回的好处是:
如给收藏的商品数量加一:
const dbCmd = db.command
db.collection('user').where({
_id: 'my-doc-id'
}).update({
count: {
fav: dbCmd.inc(1)
}
}).then(function(res) {
})
复制代码
// 更新前
{
"_id": "xxx",
"name": "Hello",
"count": {
"fav": 0,
"follow": 0
}
}
// 更新后
{
"_id": "xxx",
"name": "Hello",
"count": {
"fav": 1,
"follow": 0
}
}
复制代码
更新指令。用于指示字段自乘某个值。
如下示例将count内的fav字段乘10
const dbCmd = db.command
db.collection('user').where({
_id: 'my-doc-id'
}).update({
count: {
fav: dbCmd.mul(10)
}
}).then(function(res) {
})
复制代码
// 更新前
{
"_id": "xxx",
"name": "Hello",
"count": {
"fav": 2,
"follow": 0
}
}
// 更新后
{
"_id": "xxx",
"name": "Hello",
"count": {
"fav": 20,
"follow": 0
}
}
复制代码
更新指令。用于表示删除某个字段。如某人删除了本身一条商品评价中的评分:
const dbCmd = db.command
db.collection('comments').doc('comment-id').update({
rating: dbCmd.remove()
}).then(function(res) {
})
复制代码
// 更新前
{
"_id": "xxx",
"rating": 5,
"comment": "xxx"
}
// 更新后
{
"_id": "xxx",
"comment": "xxx"
}
复制代码
向数组尾部追加元素,支持传入单个元素或数组
const dbCmd = db.command
db.collection('comments').doc('comment-id').update({
// users: dbCmd.push('aaa')
users: dbCmd.push(['c', 'd'])
}).then(function(res) {
})
复制代码
// 更新前
{
"_id": "xxx",
"users": ["a","b"]
}
// 更新后
{
"_id": "xxx",
"users": ["a","b","c","d"]
}
复制代码
删除数组尾部元素
const dbCmd = db.command
db.collection('comments').doc('comment-id').update({
users: dbCmd.pop()
}).then(function(res) {
})
复制代码
// 更新前
{
"_id": "xxx",
"users": ["a","b"]
}
// 更新后
{
"_id": "xxx",
"users": ["a"]
}
复制代码
向数组头部添加元素,支持传入单个元素或数组。使用同push
const dbCmd = db.command
db.collection('comments').doc('comment-id').update({
// users: dbCmd.push('aaa')
users: dbCmd.unshift(['c', 'd'])
}).then(function(res) {
})
复制代码
// 更新前
{
"_id": "xxx",
"users": ["a","b"]
}
// 更新后
{
"_id": "xxx",
"users": ["c","d","a","b"]
}
复制代码
删除数组头部元素。使用同pop
const dbCmd = db.command
db.collection('comments').doc('comment-id').update({
users: dbCmd.shift()
}).then(function(res) {
})
复制代码
// 更新前
{
"_id": "xxx",
"users": ["a","b"]
}
// 更新后
{
"_id": "xxx",
"users": ["b"]
}
复制代码