任何一個大型的應(yīng)用程序和服務(wù),都必須會使用到高性能的數(shù)據(jù)存儲解決方案,用來準確(ACID,原子性Atomicity、一致性Consistency、隔離性Isolation、持久性Durability,可以拓展了解一下)、快速、可靠地存儲和檢索用戶的賬戶信息、商品以及商品交易信息、產(chǎn)品數(shù)據(jù)、資訊文章等等等等,而云開發(fā)就自帶高性能、高可用、高拓展性且安全的數(shù)據(jù)庫。
在操作數(shù)據(jù)庫時,我們要對數(shù)據(jù)庫database、集合collection、記錄doc以及字段field要有一定的了解,首先要記住這些對應(yīng)的英文單詞,當(dāng)你要操作某個記錄doc的字段內(nèi)容時,就像投送快遞一樣,要先搞清楚它到底在哪個數(shù)據(jù)庫、在哪個集合、在哪個記錄里,一級一級的去找。操作數(shù)據(jù)庫通常都是對數(shù)據(jù)庫、集合、記錄、字段進行增、刪、改、查,當(dāng)你清楚了這些,操作數(shù)據(jù)庫就不會迷糊了。
我們可以結(jié)合Excel以及MySQL(之前沒有接觸過MySQL也沒有關(guān)系,只看與Excel的對應(yīng)就行)來理解云開發(fā)的數(shù)據(jù)庫。
云數(shù)據(jù)庫 | MySQL數(shù)據(jù)庫 | Excel文件 |
---|---|---|
數(shù)據(jù)庫database | 數(shù)據(jù)庫 database | 工作簿 |
集合 collection | 表 table | 工作表 |
字段field | 數(shù)據(jù)列column | 數(shù)據(jù)表的每一列 |
記錄 record/doc | 記錄row | 數(shù)據(jù)表除開第一行的每一行 |
我們現(xiàn)在來創(chuàng)建一個books的集合(相當(dāng)于創(chuàng)建一張Excel表),用來存放圖書館里面書籍的信息,比如這樣一本書:
書名title | JavaScript權(quán)威指南(第6版) | |
---|---|---|
作者author | 弗蘭納根(David Flanagan) | |
標準書號isbn | 9787111376613 | |
出版信息publishInfo | 出版社press | 機械工業(yè)出版社 |
出版年份year | 2012 |
打開云開發(fā)控制臺的數(shù)據(jù)庫標簽,新建集合books,然后選擇該集合,給books里添加記錄(類似于填寫Excel含字段的第一行和其中一行關(guān)于書的信息記錄),依次添加字段:
在數(shù)據(jù)庫創(chuàng)建之后,我們需要在云開發(fā)控制臺-數(shù)據(jù)庫-集合的權(quán)限設(shè)置標簽對數(shù)據(jù)庫進行權(quán)限設(shè)置。數(shù)據(jù)庫的權(quán)限分為小程序端和服務(wù)端(云函數(shù)、云開發(fā)控制臺)。服務(wù)端擁有讀寫所有數(shù)據(jù)的讀寫權(quán)限,所以這里的權(quán)限設(shè)置只是在設(shè)置小程序端的用戶對數(shù)據(jù)庫的操作權(quán)限。權(quán)限控制分簡易權(quán)限控制和自定義權(quán)限(也就是安全規(guī)則),建議開發(fā)者用安全規(guī)則取代簡易的權(quán)限控制。
技術(shù)文檔:權(quán)限控制
要使用自定義權(quán)限(也就是安全規(guī)則)來全面取代簡易的權(quán)限控制,我們需要了解4個簡易的權(quán)限控制所表示的意思,以及安全規(guī)則應(yīng)該如何一一取代它們,也就是我們在配置集合的權(quán)限時,不再選擇簡易的權(quán)限控制,而是統(tǒng)一選擇自定義權(quán)限,填寫與之對應(yīng)的json規(guī)則即可。
安全規(guī)則可以讓更加靈活而又明確地自定義前端數(shù)據(jù)庫讀寫權(quán)限的能力,通過配置安全規(guī)則,開發(fā)者可以精細化的控制集合中所有記錄的讀read、寫write權(quán)限。其中write權(quán)限還可以細分為create新建、update更新、delete刪除等權(quán)限,還支持比較、邏輯運算符進行更加精細化的權(quán)限配置。
所有用戶可讀,僅創(chuàng)建者可讀寫:比如用戶發(fā)的帖子、評論、文章,這里的創(chuàng)建者是指小程序端的用戶,也就是存儲UGC(用戶產(chǎn)生內(nèi)容)的集合要設(shè)置為這個權(quán)限;
{
"read": true,
"write": "doc._openid == auth.openid"
}
僅創(chuàng)建者可讀寫:比如私密相冊,用戶的個人信息、訂單,也就是只能用戶自己讀與寫,其他人不可讀寫的數(shù)據(jù)集合;
{
"read": "doc._openid == auth.openid",
"write": "doc._openid == auth.openid"
}
所有人可讀:比如資訊文章、商品信息、產(chǎn)品數(shù)據(jù)等你想讓所有人可以看到,但是不能修改的內(nèi)容;
{
"read": true,
"write": false
}
所有用戶不可讀寫:如后臺用的不暴露的數(shù)據(jù),只能你自己看到和修改的數(shù)據(jù);
{
"read": false,
"write": false
}
小程序端 API 擁有嚴格的調(diào)用權(quán)限控制,比如在小程序端A用戶是不能修改B用戶的數(shù)據(jù)的,沒有這樣的權(quán)限,在小程序端只能修改非敏感且只是針對單個用戶的數(shù)據(jù);對于有更高安全要求的數(shù)據(jù),我們可以在云函數(shù)內(nèi)通過服務(wù)端 API 來進行操作。
如果數(shù)據(jù)庫集合里的數(shù)據(jù)是通過導(dǎo)入的方式獲取的,這個集合的權(quán)限默認為“僅創(chuàng)建者可讀寫”,這個權(quán)限在服務(wù)端(云函數(shù))可以調(diào)用,但是在小程序端可能會返回空數(shù)組哦,所以一定要記得根據(jù)情況修改權(quán)限。
小程序端與云函數(shù)的服務(wù)端無論是在權(quán)限方面、API的寫法上(有時看起來一樣,但是寫法不一樣),還是在異步處理上(比如服務(wù)端不再使用success、fail、complete回調(diào),而是返回Promise對象),都存在非常多的差異,這一點要分清楚。
查詢集合collection里的記錄是云開發(fā)數(shù)據(jù)庫操作最重要的知識,在上一節(jié)我們已經(jīng)將中國城市經(jīng)濟數(shù)據(jù)china.csv的數(shù)據(jù)導(dǎo)入到了集合china之中,并已經(jīng)設(shè)置好了集合的權(quán)限為“所有人可讀,僅創(chuàng)建者可讀寫”(或使用安全規(guī)則),接下來我們就以此為例并結(jié)合中國城市經(jīng)濟線上excel版來講解數(shù)據(jù)庫的查詢。在中國城市經(jīng)濟線上excel版以及云開發(fā)控制臺china集合里,我們可以看到中國332個城市的名稱city、省份province、市區(qū)面積city_area、建成區(qū)面積builtup_area、戶籍人口reg_pop、常住人口resident_pop、GDP的數(shù)據(jù)。
查詢中國GDP在3000億元以上的前10個城市,并要求不顯示_id字段,顯示城市名、所在省份以及GDP,并按照GDP大小降序排列。
使用開發(fā)者工具新建一個chinadata頁面,然后再在index.js的onLoad生命周期函數(shù)里輸入以下代碼。操作集合里的數(shù)據(jù)涉及的知識點非常繁雜,下面的案例相對比較完整,便于大家有一個整體性的理解:
const db = wx.cloud.database() //獲取數(shù)據(jù)庫的引用
const _ = db.command //獲取數(shù)據(jù)庫查詢及更新指令
db.collection("china") //獲取集合china的引用
.where({ //查詢的條件指令where
gdp: _.gt(3000) //查詢篩選條件,gt表示字段需大于指定值。
})
.field({ //顯示哪些字段
_id:false, //默認顯示_id,這個隱藏
city: true,
province: true,
gdp:true
})
.orderBy('gdp', 'desc') //排序方式,降序排列
.skip(0) //跳過多少個記錄(常用于分頁),0表示這里不跳過
.limit(10) //限制顯示多少條記錄,這里為10
.get() //獲取根據(jù)查詢條件篩選后的集合數(shù)據(jù)
.then(res => {
console.log(res.data)
})
.catch(err => {
console.error(err)
})
大家可以留意一下數(shù)據(jù)查詢的鏈式寫法, wx.cloud.database().collection('數(shù)據(jù)庫名').where().get().then().catch(),前半部分是數(shù)據(jù)查詢時對對象的引用和方法的調(diào)用;后半部分是Promise對象的方法,Promise對象是get的返回值。寫的時候為了讓結(jié)構(gòu)更加清晰,我們做了換行處理,寫在同一行也是可以的。
在上面的案例中,就包含了構(gòu)建查詢條件的五個方法: Collection.where()、 Collection.field()、 Collection.orderBy()、 Collection.skip()、 Collection.limit(),這五個方法是可以單獨拆開使用的,比如只使用where或只使用field、limit,也可以從這5個中抽幾個組合在一起使用,還可以一次查詢里寫多個相同的方法,比如orderBy、where可以寫多次相同的。
不過值得注意的是這5個方法順序不同查詢的結(jié)果有時也會有所不同(比如orderBy多次打亂順序的情況下),查詢性能也會有所不同。通常skip最好放在后面,不要讓skip略過大量數(shù)據(jù)。skip().limit()和limit().skip()效果是等價的。構(gòu)建查詢條件的5個方法是基于集合引用Collection的,就拿where來說,不能寫成 wx.cloud.database().where(),也不能是 wx.cloud.database().collection("china").doc.where(),只能是 wx.cloud.database().collection("china").where(),也就是只能用于查詢集合collection里的記錄。
技術(shù)文檔:Collection.where
技術(shù)文檔:Collection.field
技術(shù)文檔:Collection.orderBy
技術(shù)文檔:Collection.skip
技術(shù)文檔:Collection.limit
傳入的對象的每個 <key, value> 構(gòu)成一個篩選條件,有多個 <key, value> 則表示需同時滿足這些條件,是 與的關(guān)系,如果需要 或關(guān)系,可使用 command.or
指令用于查詢時,都會寫在where內(nèi),主要對字段的值進行比較和邏輯的篩選判斷。數(shù)據(jù)庫 API 提供了大于、小于等多種查詢指令,這些指令都暴露在 db.command 對象上。
指令Command可以分為查詢指令和更新指令,這兩者的用法有很大的區(qū)別,查詢指令用于db.collection的where條件篩選,而更新指令則是用于db.collection.doc的update請求的字段的更新里,這兩者的區(qū)別在后面我們也會反復(fù)提及。
下面我們把查詢指令的比較操作符和邏輯操作符整理成了一張表格,并附上相應(yīng)的技術(shù)文檔,方便大家對它們有一個清晰而整體的認識。 查詢指令之比較
查詢指令之比較 | |||
---|---|---|---|
gt | 大于 | lt | 小于 |
eq | 等于 | neq | 不等于 |
lte | 小于或等于 | gte | 大于或等于 |
in | 在數(shù)組中 | nin | 不在數(shù)組中 |
查詢指令之邏輯 | |||
and | 條件與 | or | 條件或 |
not | 條件非 | nor | 都不 |
指令command是基于database數(shù)據(jù)庫引用的,我們以大于gt在小程序端(以大于3000為例)的完整寫法為例:
wx.cloud.database().command.gt(3000)
為了簡便,通常我們會把 wx.cloud.database()會賦值給一個變量,如 db, db.command又會賦值給 ,使用時最終被簡化為 .gt(3000)。通過一層一層的聲明變量并賦值,大大簡化了指令的寫法,大家可以在其他指令都沿用這種寫法。
相比于其他的比較指令等于eq和不等于neq操作符的用法非常豐富,它可以進行數(shù)值比較,我們查詢某個字段比如GDP等于某個數(shù)值如17502.8億的城市:
.where({
gdp: _.eq(17502.8),
})
它還可以進行字符串的匹配,比如我們查詢某個字段比如city完整匹配一個字符串如深圳:
.where({
city: _.eq("深圳"),
})
注意:在查詢時,gdp: _.eq(17502.8)的效果等同于gdp:17502.8,而city: _.eq(“深圳”)等同于city:”深圳”,雖然兩種方式查詢的結(jié)果都是一致的,但是它們的原理不同,前者用的是等于指令,后者用的是傳遞對象值。
eq還可以用于字段的值是數(shù)組以及對象的情況,在后面的章節(jié)我們會再來介紹。
查詢廣東省內(nèi)、GDP在3000億以上且在1萬億以下的城市。在廣東省內(nèi)也就是讓字段province的值等于”廣東”,而GDP的要求則是GDP這個字段同時滿足大于3000億且小于1萬億,這時就需要用到and(條件與,也就是且的意思):
.where({
province:_.eq("廣東"),
gdp:_.gt(3000).and(_.lt(10000))
})
上面的案例中where內(nèi)的兩個條件, province:.eq("廣東")和 gdp:.gt(3000).and(_.lt(10000))帶有跨字段的條件與and(也就是且)的關(guān)系,那如何實現(xiàn)跨字段的條件或or呢?
查詢中國GDP在3000億元以上且常住人口在500萬以上或建城區(qū)面積在300平方公里以上的前20個大城市。這里常住人口和建成區(qū)面積只需要滿足其中一個條件即可,這就涉及到條件或or(注意下面代碼的格式寫法):
.where(
{
gdp: _.gt(3000),
resident_pop:_.gt(500),
},
_.or([{
builtup_area: _.gt(300)}
]),
)
注意上面三個條件, gdp: _.gt(3000)和 residentpop:.gt(500)是邏輯與,而與 builtuparea: .gt(300)}的關(guān)系是邏輯或。 _.or([{條件一 },{條件二 }])內(nèi)是一個數(shù)組,條件一與條件二又構(gòu)成邏輯與的關(guān)系。
正則表達式能夠靈活有效匹配字符串,可以用來檢查一個串里是否含有某種子串,比如“CloudBase技術(shù)訓(xùn)練營”里是否含有”技術(shù)”這個詞。云數(shù)據(jù)庫正則查詢支持UTF-8的格式,可以進行中英文的模糊查詢。正則查詢也是寫在where字段的條件篩選里。
技術(shù)文檔:Database.RegExp
我們可以用正則查詢來查詢某個字段,比如city城市名稱內(nèi),包含某個字符串比如”州”的城市:
.where({
city: db.RegExp({
regexp: '州',
options: 'i',
})
})
注意這里的city是字段,db.RegExp()里的regexp是正則表達式,而options是flag,i是flag的值表示不區(qū)分字母的大小寫。當(dāng)然我們也可以直接在where內(nèi)用JavaScript的原生寫法或調(diào)用 RegExp對象的構(gòu)造函數(shù)。比如上面的案例也可以寫成:
//JavaScript原生正則寫法
.where({
city:/州/i
})
//JavaScript調(diào)用RegExp對象的構(gòu)造函數(shù)寫法
.where({
city: new db.RegExp({
regexp: "州",
options: 'i',
})
})
數(shù)據(jù)庫查詢的正則表達式也支持模板字符串,比如我們可以先聲明const cityname=”州”,然后用模板字符串包住cityname變量:
city: db.RegExp({
regexp:`${cityname}`,
options: 'i',
})
正則表達式的用法是非常繁雜的,關(guān)于正則表達式的知識可以去搜索了解更多細節(jié)。
技術(shù)文檔:正則表達式
值得注意的是,在數(shù)據(jù)庫查詢時應(yīng)盡可能避免過度使用正則表達式來做復(fù)雜的匹配,尤其是用戶訪問觸發(fā)較多的場景,通常情況下數(shù)據(jù)查詢的響應(yīng)時間(無論是小程序端還是云函數(shù)端)最好要低于500ms。
在前面我們已經(jīng)介紹了集合數(shù)據(jù)請求的查詢方法get,除了get查詢外,請求的方法還有add新增,remove刪除、update改寫/更新、count統(tǒng)計以及watch監(jiān)聽,這些方法都是基于數(shù)據(jù)庫集合的引用Collection的,接下來我們再來介紹如何基于Collection新增記錄和統(tǒng)計記錄的數(shù)量。
基于數(shù)據(jù)庫集合的引用Collection所查詢到的記錄都是多條記錄,也就是說我們可以對N條記錄進行增、刪、改、查等操作,不過目前還不支持在小程序端進行多條記錄的update和remove,只能在云函數(shù)端進行這樣的操作。
統(tǒng)計記錄Collection.count
統(tǒng)計集合記錄數(shù)或統(tǒng)計查詢語句對應(yīng)的結(jié)果記錄數(shù)。小程序端與云函數(shù)端的表現(xiàn)會有如下差異:小程序端:注意與集合權(quán)限設(shè)置有關(guān),一個用戶僅能統(tǒng)計其有讀權(quán)限的記錄數(shù)云函數(shù)端:因?qū)儆诠芾矶耍虼丝梢越y(tǒng)計集合的所有記錄數(shù)。
技術(shù)文檔:Collection.count()
const db = wx.cloud.database()
const _ = db.command
db.collection("china")
.where({
gdp: _.gt(3000)
})
.count().then(res => {
console.log(res.total)
})
field、orderBy、skip、limit對count是無效的,只有where才會影響count的結(jié)果,count只會返回記錄數(shù),不會返回查詢到的數(shù)據(jù)。
在前面我們將知乎日報的數(shù)據(jù)導(dǎo)入到了zhihu_daily的集合里,接下來,我們就來給zhihu_daily新增記錄。
技術(shù)文檔:Collection.add
使用開發(fā)者工具新建一個zhihudaily的頁面,然后在zhihudaily.wxml里輸入以下代碼,新建一個綁定了事件處理函數(shù)為addDaily的button按鈕:
<button bindtap="addDaily">新增日報數(shù)據(jù)</button>
然后再在zhihudaily.js里輸入以下代碼,在事件處理函數(shù)addDaily里調(diào)用Collection.add,往集合zhihu_daily里添加一條記錄,如果傳入的記錄對象沒有 _id 字段,則由后臺自動生成 _id;若指定了 _id,則不能與已有記錄沖突。
addDaily(){
db.collection('zhihu_daily').add({
data: {
_id:"daily9718005",
title: "元素,生生不息的宇宙諸子",
images: [
"https://pic4.zhimg.com/v2-3c5d866701650615f50ff4016b2f521b.jpg"
],
id: 9718005,
url: "https://daily.zhihu.com/story/9718005",
image: "https://pic2.zhimg.com/v2-c6a33965175cf81a1b6e2d0af633490d.jpg",
share_url: "http://daily.zhihu.com/story/9718005",
body:"<p><strong><strong>謹以此文,紀念元素周期表發(fā)布 150 周年。</strong></strong></p>\r\n<p>地球,世界,和生活在這里的蕓蕓眾生從何而來,這是每個人都曾有意無意思考過的問題。</p>\r\n<p>科幻小說家道格拉斯·亞當(dāng)斯給了一個無厘頭的答案,42;宗教也給出了諸神創(chuàng)世的虛構(gòu)場景;</p>\r\n<p>最為恢弘的畫面,則是由科學(xué)給出的,另一個意義上的<strong>生死輪回,一場屬于元素的生死輪回</strong>。</p>"
}
})
.then(res => {
console.log(res)
})
.catch(console.error)
}
點擊新增日報數(shù)據(jù)的button,會看到控制臺打印的res對象里包含新增記錄的_id為我們自己設(shè)置的daily9718005。打開云開發(fā)控制臺的數(shù)據(jù)庫標簽,打開集合zhihu_daily,翻到最后一頁,就能看到我們新增的記錄啦。
注意和導(dǎo)入的數(shù)據(jù)不同的是,在小程序端新增記錄,都會自動添加一個_openid的字段,它的值等于用戶 openid,_openid的值是不允許修改的。當(dāng)我們把集合的權(quán)限改為僅創(chuàng)建者可讀寫,或所有人可讀,僅創(chuàng)建者可讀寫,在小程序端查詢或更新記錄時,會自動添加一個條件,
.where({
_openid:"當(dāng)前用戶的openid"
})
所以這就是為什么盡管集合里面有數(shù)據(jù),但是由于有了這個條件,只要記錄里沒有_openid或openid不匹配就查詢不到記錄。
集合請求方法注意事項
get、update、count、remove、add等都是請求,在小程序端可以有callback和promise兩種寫法,但是在云函數(shù)端只能用promise,不能用callback。為了方便,建議大家統(tǒng)一使用promise的寫法,也就是then、catch。
get、update、count、remove、add請求不能在一個數(shù)據(jù)庫引用里同時存在。比如不能又是get(),又是count()的,不能這么寫:
db.collection('china').where({
_openid: 'xxx',
}).get().count().add()
在云開發(fā)能力章節(jié)我們已經(jīng)介紹過如何在云函數(shù)端調(diào)用數(shù)據(jù)庫,這里也是一樣。新建一個云函數(shù)chinadata,然后在 exports.main = async (event, context) => {}輸入以下代碼,注意是 const db = cloud.database(),wx. cloud.database(),云函數(shù)端的數(shù)據(jù)庫引用和小程序端有所不同:
const db = cloud.database()
const _ = db.command
return await db.collection("china")
.where({
gdp: _.gt(3000)
})
.field({
_id: false,
city: true,
province: true,
gdp: true
})
.orderBy('gdp', 'desc')
.skip(0)
.limit(10)
.get()
try/catch async錯誤處理
當(dāng) async 函數(shù)中只要一個 await 出現(xiàn) reject 狀態(tài),則后面的 await 都不會被執(zhí)行。如果有多個 await 則可以將其都放在 try/catch 中。
然后右鍵chinadata云函數(shù)根目錄選擇在終端中打開,輸入npm install,之后上傳并部署所有文件。
?
在前面我們了解到,調(diào)用云函數(shù)可以使用本地調(diào)試、云端測試,我們還可以在小程序端調(diào)用云函數(shù),將云函數(shù)的數(shù)據(jù)返回到小程序端來。使用開發(fā)者工具在chinadata.wxml里輸入以下代碼,也就是我們通用點擊按鈕觸發(fā)事件處理函數(shù):
<button bindtap="callChinaData">調(diào)用chinadata云函數(shù)</button>
再在事件處理函數(shù)里調(diào)用云函數(shù),在chinadata.js里輸入getChinaData事件處理函數(shù)來調(diào)用chinadata云函數(shù):
getChinaData() {
wx.cloud.callFunction({
name: 'chinadata',
success: res => {
console.log("云函數(shù)返回的數(shù)據(jù)",res.result.data)
},
fail: err => {
console.error('云函數(shù)調(diào)用失?。?, err)
}
})
},
在模擬器里點擊調(diào)用chinadata云函數(shù)的button按鈕,就能在控制臺里看到云函數(shù)返回的查詢到的結(jié)果,大家可以通過setData的方式將查詢的結(jié)果渲染到小程序頁面,這里就不介紹啦。
基于數(shù)據(jù)庫集合的引用Collection,我們可以先匹配 where 語句查詢到相關(guān)條件的多條記錄,再來調(diào)用Collection.remove()來進行刪除。五個查詢方法,skip和limit不支持,field、orderBy沒有意義,只有where條件可以用來篩選記錄。數(shù)據(jù)一旦刪除就不能再找回了。
技術(shù)文檔:Collection.remove()
我們可以把之前建好的chinadata云函數(shù) exports.main = async (event, context) => {}里的代碼修改為如下,即刪除省份province為廣東的所有數(shù)據(jù):
return await db.collection('china')
.where({
province:"廣東"
})
.remove()
在模擬器里點擊調(diào)用chinadata云函數(shù)的button按鈕,就能在控制臺里看到云函數(shù)返回的對象,其中包含stats: {removed: 22},即刪除了22條數(shù)據(jù)。
更新多條記錄Collection.update
我們可以把之前建好的chinadata云函數(shù) exports.main = async (event, context) => {}里的代碼修改為如下,也就是先查詢省份province為湖北的記錄,給這個記錄更新一個字段英文省份名pro-en:
return await db.collection('china')
.where({
province:"湖北"
})
.update({
data: {
"pro-en": "Hubei"
},
})
這里要注意的是,pro-en這個字段之前是沒有的,通過Collection.update不只是起到更新的作用,還可以批量新增字段并賦值,也就是update時記錄里有相同字段就更新,沒有就新增; "pro-en": "Hubei",直接使用pro-en會報錯,用雙引號效果等價。
如果你想給導(dǎo)入的數(shù)據(jù)添加_openid字段,只用云函數(shù)是沒法實現(xiàn)的,因為云函數(shù)沒有用戶的登錄態(tài)。我們需要先在小程序端調(diào)用云函數(shù)比如login返回openid,再將openid的值再傳給chinadata云函數(shù),才能給記錄添加openid。
在前面我們已經(jīng)了解了基于集合引用Collection構(gòu)建查詢條件的5個方法,以及一些請求方法,接下來我們來講一下基于集合記錄引用Document的四個請求方法:獲取單個記錄數(shù)據(jù)Document.get()、刪除單個記錄Document.remove()、更新單個記錄Document.update()、替換更新單個記錄Document.set()。和基于Collection不一樣的是,前者的增刪改查是可以批量多條的,而基于Document則是操作單條記錄。
查詢集合collection里的記錄常用于獲取文章、資訊、商品、產(chǎn)品等等的列表;而查詢單個記錄doc的字段值則常用于這些列表里的詳情內(nèi)容。如果你在開發(fā)中需要增刪改查某個記錄的字段值,為了方便讓程序可以根據(jù)_id找到對應(yīng)的記錄,建議在創(chuàng)建記錄的時候_id用程序有規(guī)則的生成。
集合里的每條記錄都有一個 _id 字段用以唯一標志一條記錄,_id 的數(shù)據(jù)格式可以是number數(shù)字,也可以是string字符串。這個_id是可以自定義的,當(dāng)導(dǎo)入記錄或?qū)懭胗涗洓]有自定義時系統(tǒng)會自動生成一個非常長的字符串。查詢記錄doc的字段field值就是基于_id的。
技術(shù)文檔:獲取單個記錄數(shù)據(jù)Document.get()
比如我們查詢其中知乎日報的一篇文章(也就是其中一條記錄)的數(shù)據(jù),使用開發(fā)者工具zhihudaily頁面的zhihudaily.js的onLoad生命周期函數(shù)里輸入以下代碼(db不要重復(fù)聲明):
db.collection('zhihu_daily').doc("daily9718006")
.get()
.then(res => {
console.log('單個記錄的值',res.data)
})
.catch(err => {
console.error(err)
})
},
如果集合的數(shù)據(jù)是導(dǎo)入的,那_id是自動生成的,自動生成的_id是字符串string,所以doc內(nèi)使用了單引號(雙引號也是可以的哦),如果你自定義的_id是number類型,比如自定義的_id為20191125,查詢時為doc(20191125)即可,這只是基礎(chǔ)知識啦。
技術(shù)文檔:刪除單個記錄Document.remove()
removeDaily(){
db.collection('zhihu_daily').doc("daily9718006")
.remove()
.then(console.log)
.catch(console.error)
}
技術(shù)文檔:更新單個記錄Document.update()
updateDaily(){
db.collection('zhihu_daily').doc("daily9718006")
.update({
data:{
title: "【知乎日報】元素,生生不息的宇宙諸子",
}
})
},
技術(shù)文檔:替換更新單個記錄Document.set()
setDaily(){
db.collection('zhihu_daily').doc("daily9718006")
.set({
data: {
"title": "為什么狗會如此親近人類?",
"images": [
"https://pic4.zhimg.com/v2-4cab2fbf4fe9d487910a6f2c54ab3ed3.jpg"
],
"id": 9717547,
"url": "https://daily.zhihu.com/story/9717547",
"image": "https://pic4.zhimg.com/v2-60f220ee6c5bf035d0eaf2dd4736342b.jpg",
"share_url": "http://daily.zhihu.com/story/9717547",
"body": "<p>讓狗從兇猛的野獸變成忠實的愛寵,涉及了宏觀與微觀上的兩層故事:我們?nèi)绾卧诤暧^上馴養(yǎng)了它們,以及這些馴養(yǎng)在生理層面究竟意味著什么。</p>\r\n<p><img class=\"content-image\" src=\"http://pic1.zhimg.com/70/v2-4147c4b02bf97e95d8a9f00727d4c184_b.jpg\" alt=\"\"></p>\r\n<p>狗是灰狼(Canis lupus)被人類馴養(yǎng)后形成的亞種,至少可以追溯到 1 萬多年以前,是人類成功馴化的第一種動物。在這漫長的歲月里,人類的定向選擇強烈改變了這個馴化亞種的基因頻率,使它呈現(xiàn)出極高的多樣性,尤其體現(xiàn)在生理形態(tài)上。</p>"
}
})
}
更多建議: