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"]
}
複製代碼