版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領
文檔簡介
1、開發(fā)向?qū)洗胃臅r間2015/12/08創(chuàng)立一個帳號首先,注冊并登錄Wilddog賬號,進入控制面板。然后,在控制面板中,添加一個新的應用。你會得到一個應用的URLs:/<appld>.wilddogio/。你可以把這個URL理解為云端數(shù)據(jù)庫的地址。安裝Wilddog使用JavascriptSDK非常簡單。你只需在HTML文件中參加一個script標簽。<scriptsrc=></script>Wilddognode.js版API與javascript版完全一樣。Wilddog客戶端在Node.js上運行非常簡單,首先需要通過npm安裝Wilddog模塊$n
2、pminstallwilddog-save使用require在你的應用中使用wilddogvarWilddog=require("wilddog");Typescript用戶typescript調(diào)用原生js需要有一個.d.ts文件。在這里可以找到在Ionic工程中使用Ionic是一個利用html5開發(fā)混合手機APP的前端SDK,由于Ionic使用Angular,所以開發(fā)者在開發(fā)IonicAPP時可以使用wild-angular來簡化wilddog的一些操作。如今我們可以使用Ionic提供的命令行命令來安裝Ionic:$npminstall-gionic假設在Mac電腦開發(fā)應
3、用并且希望運行在ios設備上,需要先安裝XCode,然后用npm安裝ios-sim:$npminstall-gios-sim如今我們可以使用Ionic的命令行工具來創(chuàng)立一個空白的Ionic應用模板:$ionicstartmyappblank使用下面的命令行可以告訴Ionic我們的應用要適配ios和Android:$ionicplatformaddios$ionicplatformaddandroid集成Wilddog:在html文件中,在引入自己的app.js文件之前,我們引入Wilddog和wild-angular作為依賴,<!-Wilddog-><scriptsrc=&g
4、t;</script><!-wild-angular-><scriptsrc="s:></script>在自己的app.js文件中把Wilddog作為依賴注入到我們的module中:angular.module("starter","ionic","wilddog")如今我們就可以使用wild-angular的$wilddogObject、$wilddogArray、$wilddogAuth來對數(shù)據(jù)進展操作了。提示和建議1,我們建議你直接使用野狗官方提供的SDK地址。這樣,你將
5、無需更新任何代碼,即可獲得更新。2,wilddog.js是經(jīng)過大量測試的RELEASE版本。3,野狗全站均支持Spdy3.1和Gzip壓縮。我們正在嘗試更高的壓縮比,例如SDCH,2來進一步提升靜態(tài)資源加載速度。4,不用擔憂s的性能。我們對s進展了極致的優(yōu)化。野狗的官網(wǎng),直到windows.onload事件觸發(fā),也只花費了不到500mso2.理解數(shù)據(jù)數(shù)據(jù)是一棵JSON樹所有的數(shù)據(jù)都存儲在各個JSON對象中,沒有任何表的概念。當你把數(shù)據(jù)添加到這棵json樹中,這些數(shù)據(jù)就變成這棵樹的子樹。比方,我們在users/mchen下增加widget后,我們的數(shù)據(jù)是這樣的"users":
6、"mchen":"friends":"brinchen":true,"name":"MaryChen",/新數(shù)據(jù)節(jié)點會增加在已經(jīng)存在的JSON樹中"widgets":"one":true,"three":true,"brinchen":.,"hmadi":.創(chuàng)立一個Wilddog對象引用在html中讀寫wilddog數(shù)據(jù),需要創(chuàng)立一個Wilddog對象引用,要操作和同步哪些數(shù)據(jù)取決于創(chuàng)立Wildd
7、og對象引用時傳入的URLnewWilddog('s:/<appId>.wilddogio/web/data');創(chuàng)立一個Wilddog引用并不是直接訪問這個URL,或創(chuàng)立一個連接。數(shù)據(jù)直到需要的時候才會傳輸。一旦這個數(shù)據(jù)被查詢,這個數(shù)據(jù)會一直與效勞端保持一致。你可以直接訪問一個子節(jié)點:newWilddog('s:<appId>.wilddogio/web/data/users/mchen/name');你還可以通過child接口進展相對途徑訪問:varrootRef=newWilddog('s:/<appId>.wi
8、lddogio/web/data');rootRef.child('users/mchen/name');Wilddog中的數(shù)組Wilddog并不天然支持數(shù)組,當我們想存數(shù)組時,我們把數(shù)組變成對象/原始數(shù)據(jù)'hello','world'/存儲后的新數(shù)據(jù)0:'hello',1:'world'需要注意的是,假設某節(jié)點的所有子節(jié)點的key都是整數(shù),且0到key的最大值之間,超過一半的key都有非空的值,那么wilddog客戶端會將它們當作數(shù)組來處理。限制和約束描繪約束備注樹的深度32key的長度768bytesU
9、TF-8編碼,不能包含.$#/和ASCII控制字符0-31和127描繪約束備注一個葉子節(jié)點的數(shù)據(jù)大小1mbUTF-8編碼通過SDK寫入的數(shù)據(jù)大小2mbUTF-8編碼限制通過REST寫入數(shù)據(jù)大4mb小限制一次能讀取的節(jié)點2000一次條件查詢能返回的最500如使用limitToFirst()、limitToLast()等大條數(shù)保存數(shù)據(jù)的方式methoddescriptionset()寫入和交換當前途徑的數(shù)據(jù)update。修改部分子節(jié)點的數(shù)據(jù)push()在當前節(jié)點下新增一個數(shù)據(jù),數(shù)據(jù)的key隨機生成methoddescriptiontransaction。一個復雜數(shù)據(jù)被并發(fā)更新導致數(shù)據(jù)錯誤,使用事務
10、防止數(shù)據(jù)被并發(fā)更新用set()寫數(shù)據(jù)set是Wilddog最根本的寫數(shù)據(jù)操作。set()設置當前節(jié)點的值,假設當前節(jié)點已經(jīng)存在值,set會將舊值交換成新值。為了理解set的工作原理,我們創(chuàng)立一個簡單博客app,這個博客的app儲存在這里:varref=newWilddog("s:<appId>.wilddogio/web/saving-data/wildblog");我們用唯一的用戶名來標識一個用戶,存儲他們的全名和生日。首先,我們創(chuàng)立一個引用,然后用set儲存數(shù)據(jù),set可以傳入string,number,boolean,object類型:varusersRe
11、f=ref.child("users");usersRef.set(alanisawesome:date_of_birth:"June23,1912",full_name:"AlanTuring",gracehop:date_of_birth:"December9,1906"full_name:"GraceHopper");這時,數(shù)據(jù)被嵌套保存到了相應的位置上,完成上面的過程,你也可以直接這樣做usersRef.child("alanisawesome" ).set(date
12、ofbirth:"June 23, 1912"full name:"Alan Turing");usersRef.child("gracehop" ).set(dateofbirth:"December 9, 1906"full name:"Grace Hopper");這兩種方式的區(qū)別是,假設/user下面原來有數(shù)據(jù)的時候,第一種方式會把數(shù)據(jù)全部覆蓋掉,而第二種方式只會覆蓋alanisawesome和gracehop兩個子節(jié)點.更新已經(jīng)存在的數(shù)據(jù)假設你想同時更新多個子節(jié)點,而不覆蓋其他的子節(jié)點
13、,你可以使用update()函數(shù):varhopperRef=usersRef.child("gracehop");hopperRef.update("nickname":"AmazingGrace");這樣會更新Grace的數(shù)據(jù),更新她的nickname。假設我們用set而不是update,date_of_birth和full_name都會被刪除。保存一個列表當多個用戶同時試圖在一個節(jié)點下新增一個子節(jié)點的時候,這時,數(shù)據(jù)就會被重寫,覆蓋。為理解決這個問題,Wilddogpush()采用了生成唯一ID作為key的方式。通過這種方式,多個
14、用戶同時在一個節(jié)點下面push數(shù)據(jù),他們的key一定是不同的。這個key是通過一個基于時間戳和隨機的算法生成的。wilddog采用了足夠多的位數(shù)保證唯一性。用戶可以用push向博客app中寫新內(nèi)容:varpostsRef=ref.child("posts");postsRef.push(author:"gracehop",title:"AnnouncingCOBOL,aNewProgrammingLanguage);postsRef.push(author:"alanisawesome",title:"TheTur
15、ingMachine");產(chǎn)生的數(shù)據(jù)有一個唯一ID:"posts":"-JRHTHaIs-jNPLXO":"author":"gracehop","title":"AnnouncingCOBOL,aNewProgrammingLanguage","-JRHTHaKuITFIhnj":"author":"alanisawesome","title":"TheTuringMachi
16、ne"獲取口!一ID調(diào)用push會返回一個引用,這個引用指向新增數(shù)據(jù)所在的節(jié)點。你可以通過調(diào)用key()來獲取這個唯一ID/通過push()來獲得一個新的數(shù)據(jù)庫地址varnewPostRef=postsRef.push(author:"gracehop",title:"AnnouncingCOBOL,aNewProgrammingLanguage");/獲取push()生成的唯一IDvarpostID=newPostRef.key();使用事務保存數(shù)據(jù)當處理可能被并發(fā)更新導致?lián)p壞的復雜數(shù)據(jù)時,比方增量計數(shù)器,我們提供了事務操作。事務操作需要提供
17、兩個參數(shù):一個更新函數(shù)和一個可選的完成callback函數(shù)。更新函數(shù)提供當前數(shù)據(jù),當前數(shù)據(jù)是云端讀取的。舉例說明,假設我們想在一個的博文上計算點贊的數(shù)量,我們可以這樣寫一個事務:varupvotesRef=newWilddog('s:<appId>.wilddogio/android/saving-data/wildblog/posts/-JRHTHaIs-jNPLXOQivY/upvotes');upvotesRef.transaction(function(current_value)/return(current_value|0)+1;);我們使用curren
18、tData.getValue!=null來判斷計數(shù)器是否為空或者是自增加。假設上面的代碼沒有使用事務,當兩個客戶端在同時試圖累加,那結果可能是為數(shù)字1且非數(shù)字2。注意:doTransaction()可能被屢次被調(diào)用,必須處理currentData變量為null的情況。當事務允許時,本地不會緩存從云端讀取的數(shù)據(jù)。更多關于事務API的文檔。到目前為止,我們已經(jīng)理解到如何向Wilddog中保存數(shù)據(jù),如今我們來看看如何查詢數(shù)據(jù)。Wilddog查詢數(shù)據(jù)的方式是綁定一個異步監(jiān)聽的回調(diào)函數(shù),每當數(shù)據(jù)被第一次查詢或者數(shù)據(jù)發(fā)生變化,這個回調(diào)函數(shù)都會被執(zhí)行。重新看博客app的例子,我們可以這樣讀取博客數(shù)據(jù):/獲得
19、一個數(shù)據(jù)庫連接實例varref=newWilddog("s:<appId>.wilddogio/web/saving-data/blog/posts");/監(jiān)聽數(shù)據(jù)ref.on("value",function(snapshot)console.log(snapshot.val();,function(errorObject)console.log("Thereadfailed:"+errorObject.code););運行這段代碼,我們會看到控制臺中打印出一個對象,包含所有的博客數(shù)據(jù)。每次當有新的博客數(shù)據(jù)被寫入時,這個
20、回調(diào)函數(shù)都會被觸發(fā)執(zhí)行。回調(diào)函數(shù)接收一個Snapshot類型作為參數(shù)。一個Snapshot對象代表的是在指定的數(shù)據(jù)途徑下,某一個時間點上數(shù)據(jù)的一個快照。調(diào)用它的val()函數(shù),可以得到一個代表當前節(jié)點數(shù)據(jù)的javascript對象。假設途徑節(jié)點下沒有數(shù)據(jù),那么這個Snapshot將為null。這個例子中我們用value,作為事件類型,用于讀取當前途徑節(jié)點下的所有數(shù)據(jù)。我們還可以使用另外三種數(shù)據(jù)事件類型。事件類型WildDog提供了四種數(shù)據(jù)事件:value,child_added,child_changed,child_removed。valuevalue事件用來讀取當前節(jié)點的靜態(tài)數(shù)據(jù)快照,va
21、lue事件在初次獲取到數(shù)據(jù)時被觸發(fā)一次,此后每當數(shù)據(jù)發(fā)生變化都會被觸發(fā)。回調(diào)函數(shù)被執(zhí)行時候,當前節(jié)點下所有數(shù)據(jù)的靜態(tài)快照會被作為參數(shù)傳入。child_added與value事件返回指定數(shù)據(jù)節(jié)點下的所有數(shù)據(jù)不同,child_added事件會為每一個現(xiàn)存的子節(jié)點數(shù)據(jù)觸發(fā)一次,此后每當有子節(jié)點數(shù)據(jù)被增加時被觸發(fā)一次?;卣{(diào)函數(shù)傳入的也是DataSnapshot對象,包含的是新增子節(jié)點的數(shù)據(jù)。假設我們只想獲取新增的博客數(shù)據(jù),可以使用child_added事件:/獲得一個數(shù)據(jù)庫連接實例varref=newWilddog("s:<appId>.wilddogio/web/saving-
22、data/blog/posts");/獲得新增加的數(shù)據(jù)ref.on("child_added",function(snapshot)varnewPost=snapshot.val();console.log("Author:"+newPost.author);console.log("Title:"+newPost.title););childchanged當子節(jié)點數(shù)據(jù)發(fā)生了改變時,childchanged事件會被觸發(fā),事件回調(diào)函數(shù)中傳入的參數(shù)是子節(jié)點改變后的數(shù)據(jù)快照。我們可以使用child_changed事件來讀取被修改的
23、博客數(shù)據(jù):/獲得一個數(shù)據(jù)庫連接實例varref=newWilddog("s:/<appId>.wilddogio/web/saving-data/blog/posts");/獲得發(fā)生改變的數(shù)據(jù)ref.on("child_changed",function(snapshot)varchangedPost=snapshot.val();console.log("Theupdatedposttitleis"+changedPost.title););childremoved當直接子節(jié)點被刪除時,chiidremoved事件被觸發(fā)
24、。事件回調(diào)函數(shù)中傳入的參數(shù)是被刪除的直接子節(jié)點的數(shù)據(jù)快照。在博客的例子中,我們可以使用child_removed事件,在有博客數(shù)據(jù)被刪除時,在控制臺中打印出來:/獲得一個數(shù)據(jù)庫連接實例varref=newWilddog("s:<appId>.wilddogio/web/saving-data/blog/posts");/獲取被刪除的數(shù)據(jù)ref.on("child_removed",function(snapshot)vardeletedPost=snapshot.val();console.log("Theblogposttitle
25、d'"+deletedPost.title+"'hasbeendeleted"););取消事件綁定通過off()函數(shù)可以取消一個事件回調(diào)函數(shù)的綁定:ref.off("value",originalCallback);一次性讀取數(shù)據(jù)在某些場景下,也許需要事件的回調(diào)函數(shù)只被觸發(fā)一次,然后立即取消??梢允褂胦nce()函數(shù):ref.once("value",function(data)/執(zhí)行業(yè)務處理,此回調(diào)函數(shù)只會被調(diào)用一次)查詢數(shù)據(jù)Wilddog支持選擇性的查詢數(shù)據(jù)。要構造一個查詢,需要先指定數(shù)據(jù)如何排序,可以使
26、用以下幾個函數(shù):orderByChild(),orderByKey(),orderByValue(),orderByPriority()。接下來,可以組合以下五個函數(shù),構造出一個復雜的條件查詢:limitToFirst(),limitToLast(),startAt(),endAt(),equalTo()。F面我們來舉例如何進展數(shù)據(jù)查詢。假設如今有一些關于恐龍的數(shù)據(jù)如下:"lambeosaurus":"height":,"length":,"weight":5000,"stegosaurus":
27、"height":4,"length":9,"weight":2500按照指定的子節(jié)點排序通過將子節(jié)點的途徑名作為參數(shù)傳遞給orderByKey(),可以實現(xiàn)按指定子節(jié)點排序。例如,要按照height進展排序,可以:varref=newWilddog("s:<appId>.wilddogio/dinosaurs");ref.orderByChild("height").on("child_added",function(snapshot)console.log(s
28、napshot.key()+"was"+snapshot.val().height+"meterstall"););不包含指定子節(jié)點的數(shù)據(jù)節(jié)點,將會按照該子節(jié)點為null進展排序,會排在最前邊。每個查詢都只能有一個排序。在一個查詢中屢次調(diào)用orderByChild()會拋出錯誤。按照數(shù)據(jù)節(jié)點名稱排序使用orderByKey()函數(shù),可以實現(xiàn)按照數(shù)據(jù)節(jié)點的名稱進展排序。下面的例子按照alpha字母順序讀取所有的恐龍數(shù)據(jù):varref=newWilddog("s:<appId>.wilddogio/dinosaurs");re
29、f.orderByKey().on("child_added",function(snapshot)console.log(snapshot.key(););按照數(shù)據(jù)節(jié)點的值排序使用orderByValue()函數(shù),我們可以按照子節(jié)點的值進展排序。假設恐龍們進展了一場運動會,我們統(tǒng)計到它們的得分數(shù)據(jù):"scores":"bruhathkayosaurus":55,"lambeosaurus":21,"linhenykus":80,"pterodactyl":93,"
30、stegosaurus":5,"triceratops":22要按照得分進展排序,我們可以構造一個這樣的查詢:varref=newWilddog("s:/<appId>.wilddogio/scores");scoresRef.orderByValue().on("value",function(snapshot)snapshot.forEach(function(data)console.log("The"+data.key()+"dinosaur'sscoreis&quo
31、t;+data.val();););按照優(yōu)先級排序關于優(yōu)先級,請參考API文檔中的相關部分。復雜查詢我們已經(jīng)理解到數(shù)據(jù)排序的函數(shù)。接下來是limit類的和range類的查詢,通過它們,可以構建出更為復雜的查詢:limit查詢limitToFirst()和limitToLast()兩個函數(shù)用于設置最大多少個子節(jié)點數(shù)據(jù)會被同步。假設我們設置為100,那么初次獲取到數(shù)據(jù)時,就只會最多觸發(fā)100次事件回調(diào)函數(shù)。假設數(shù)據(jù)庫中有少于100條消息數(shù)據(jù),child_added事件將會為每一條消息數(shù)據(jù)被觸發(fā)一次。假設消息數(shù)量多于100條,那么只有其中的100條會被觸發(fā)child_added事件。假設我們使用了l
32、imitToFirst()函數(shù),那么被觸發(fā)的100條將會是排序最前邊的100條。假設使用了limitToLast()函數(shù),那么被觸發(fā)的100條將是排序最后的100條。繼續(xù)恐龍的例子,我們可以獲得體重最大的兩種恐龍:varref=newWilddog("s:<appId>.wilddogio/dinosaurs");ref.orderByChild("weight").limitToLast(2).on("child_addedfunction(snapshot)console.log(snapshot.key(););我們?yōu)閏hil
33、d_added事件綁定的回調(diào)函數(shù)只會被執(zhí)行2次。同理,我們可以使用limitToFirst()函數(shù)查詢最矮的兩種恐龍:varref=newWilddog("s:<appId>.wilddogio/dinosaurs");ref.orderByChild("height").limitToFirst(2).on("child_added”,function(snapshot)console.log(snapshot.key(););我們也可以組合orderByValue()函數(shù)來使用limit類的查詢。假設要構造出恐龍運動會得分的前3
34、名,我們可以構造這樣一個查詢:varref=newWilddog("s:<appId>.wilddogio/scores");scoresRef.orderByValue().limitToLast(3).on("value",function(snapshot)snapshot.forEach(function(data)console.log("The"+data.key()+"dinosaur'sscoreis"+data.val();););range查詢使用startAt(),endA
35、t(),和equalTo()函數(shù),我們可以任意指定任意值的范圍進展查詢。例如,假設要查詢所有至少3米高以上的恐龍,可以組合orderByChild()和startAt()查詢:varref=newWilddog("s:<appId>.wilddogio/dinosaurs");ref.orderByChild("height").startAt(3).on("child_added",function(snapshot)console.log(snapshot.key();我們可以使用endAt()來查詢按照字母排序,所有
36、名字排在Pterodactyl之前的恐龍:varref=newWilddog("s:<appId>.wilddogio/dinosaurs");ref.orderByKey().endAt("pterodactyl").on("child_added",function(snapshot)console.log(snapshot.key(););注意,startAt()和endAt()都是包含邊界值的,也就是說“pterodactyl'符合上邊的查詢條件。我們可以同時使用startAt()和endAt()來限定一個
37、范圍。下面的例子查詢出所有名字以字母“6開頭的恐龍:varref=newWilddog("s:<appId>.wilddogio/dinosaurs");ref.orderByKey().startAt("b").endAt("b").on("child_added",function(snapshot)console.log(snapshot.key(););這個例子中使用的“下符號是ASCII中的126字符。因為它排在所有常規(guī)的ASCII字符之后,所以這個查詢匹配所有以b開頭的值。使用equalTo
38、()函數(shù),可以進展精準的查詢。例如,查詢所有的25米高的恐龍:varref=newWilddog("s:<appId>.wilddogio/dinosaurs");ref.orderByChild("height").equalTo(25).on("child_added",function(snapshot)console.log(snapshot.key(););同樣的,startAt(),endAt()函數(shù)也可以和orderByValue()函數(shù)組合進展range查詢。總結組合這些函數(shù),我們可以構造出各種復雜的查詢。
39、例如,要找出長度小于Stegosaurus但最接近的恐龍的名字:varref=newWilddog("s:<appId>.wilddogio/dinosaurs");ref.child("stegosaurus").child("height").on("value",function(stegosaurusHeightSnapshot)varfavoriteDinoHeight=stegosaurusHeightSnapshot.val();varqueryRef=ref.orderByChild(&
40、quot;height").endAt(favoriteDinoHeight).limitToLast(2)queryRef.on("value",function(querySnapshot)if(querySnapshot.numChildren()=2)/數(shù)據(jù)是按照height字段的值升序排列的,所以我們需要獲得第一個元素。querySnapshot.forEach(function(dinoSnapshot)console.log("Thedinosaurjustshorterthanthestegasaurusis"+dinoSnap
41、shot.key();/返回true意味著我們只需要循環(huán)forEach()一次returntrue;);elseconsole.log("Thestegosaurusistheshortestdino");););數(shù)據(jù)排序本小節(jié)介紹在使用各種排序方式時,數(shù)據(jù)終究是如何排序的。orderByChild當使用orderByChild(key)時,按照子節(jié)點的公有屬性key的value進展排序。僅當value為單一的數(shù)據(jù)類型時,排序有意義。假設key屬性有多種數(shù)據(jù)類型時,排序不固定,此時不建議使用orderByChild(key)獲取全量數(shù)據(jù),例如,"scores&qu
42、ot;:"no1":"name":"tyrannosaurus","score":"120","no2":"name":"bruhathkayosaurus","score":55,"no3":"name":"lambeosaurus”"score":21,"no4":"name":"linheny
43、kus”"score":80,"no5":"name":"pterodactyl""score":93,"no6":"name":"stegosaurus""score":5,"no7":"name":"triceratops""score":22,"no8":"name":"bronto
44、saurus""score":true霸王龍的分數(shù)是string類型,雷龍的分數(shù)是boolean類型,而其他恐龍的分數(shù)是numberic類型,此時使用orderByChild(key)獲得全量數(shù)據(jù)時,是一個看似固定的排序結果;但是配合使用limitToFirst()時,將獲得不確定的結果。Object類型數(shù)據(jù)的value值為null,不會出如今結果中。當配合使用startAt()、endAt()和equalTo()時,假設子節(jié)點的公有屬性key包含多種數(shù)據(jù)類型,將按照這些函數(shù)的參數(shù)的類型排序,即只能返回這個類型的有序數(shù)據(jù)。上面的數(shù)據(jù)假設使用orderByChild
45、('score').startAt(60).limitToFirst(4)將得到下面的結果:"no4":"name":"linhenykus""score":80,"no5":"name":"pterodactyl"score":93注意:假設path與value的總長度超過1000字節(jié)時,使用orderByChild(key)將搜索不到該數(shù)據(jù)。orderByKey當使用orderByKey()對數(shù)據(jù)進展排序時,數(shù)據(jù)將會按照下面的
46、規(guī)那么,以字段名升序排列返回。注意,節(jié)點名只能是字符串類型。1,節(jié)點名能轉(zhuǎn)換為32-bit整數(shù)的子節(jié)點優(yōu)先,按數(shù)值型升序排列。2,接下來是字符串類型的節(jié)點名,按字典序排列。orderByValue當使用orderByValue()時,按照直接子節(jié)點的value進展排序。僅當value為單一的數(shù)據(jù)類型時,排序有意義。假設子節(jié)點包含多種數(shù)據(jù)類型時,排序不固定,此時不建議使用orderByValue()獲取全量數(shù)據(jù),例如,"scores":"tyrannosaurus":"120","bruhathkayosaurus"
47、:55,"lambeosaurus":21,"linhenykus":80,"pterodactyl":93,"stegosaurus”:5,"triceratops":22,"brontosaurus":true霸王龍的分數(shù)是string類型,雷龍的分數(shù)是boolean類型,而其他恐龍的分數(shù)是numberic類型,此時使用orderByValue()獲得全量數(shù)據(jù)時,是一個看似固定的排序結果;但是配合使用limitToFirst()時,將獲得不確定的結果。Object類型數(shù)據(jù)的valu
48、e值為null,不會出如今結果中。當配合使用startAt()、endAt()和equalTo()時,假設子節(jié)點的value包含多種數(shù)據(jù)類型,將按照這些函數(shù)的參數(shù)的類型排序,即只能返回這個類型的有序數(shù)據(jù)。上面的數(shù)據(jù)假設使用orderByValue().startAt(60).limitToFirst(4)將得到下面的結果:"linhenykus":80,"pterodactyl":93注意:假設path與value的總長度超過1000字節(jié)時,使用orderByValue()將搜索不到該數(shù)據(jù)。orderByPriority當使用orderByPriorit
49、y()對數(shù)據(jù)進展排序時,子節(jié)點數(shù)據(jù)將按照優(yōu)先級和字段名進展排序。注意,優(yōu)先級的值只能是數(shù)值型或字符串。1,沒有優(yōu)先級的數(shù)據(jù)默認優(yōu)先。2,接下來是優(yōu)先級為數(shù)值型的子節(jié)點。它們按照優(yōu)先級數(shù)值排序,由小到大。3,接下來是優(yōu)先級為字符串的子節(jié)點。它們按照優(yōu)先級的字典序排列。4,當多個子節(jié)點擁有一樣的優(yōu)先級時包括沒有優(yōu)先級的情況,它們按照節(jié)點名排序。節(jié)點名可以轉(zhuǎn)換為數(shù)值類型的子節(jié)點優(yōu)先數(shù)值排序,接下來是剩余的子節(jié)點字典序排列。構造恰當?shù)腘oSQL存儲構造需要事先考慮很多因素。最重要的是,必需要知道將來數(shù)據(jù)會被如何查詢,如何存儲數(shù)據(jù)才能使查詢最方便。防止層級過深盡管可以使用JSON任意地組織數(shù)據(jù),但不同的
50、組織方式對讀取T能的影響是很大的。Wilddog的工作方式是當你查詢某個節(jié)點,Wilddog會返回這個節(jié)點下的所有子節(jié)點。所以,應該盡可能使數(shù)據(jù)扁平化,就像組織SQL關系型數(shù)據(jù)表一樣。我們不推薦這種理論/一個非常差的充滿嵌套的數(shù)據(jù)構造。請勿模擬。/對"rooms"進展遍歷查找來獲得名字需要下載很多很多的messages。"rooms":"one":"name":"roomalpha","type":"private","messages"
51、;:"m1":"sender":"mchen","message":"foo","m2":.,/非常長的messages列表對于這種嵌套存儲的設計,很難遍歷所有的數(shù)據(jù)。比方列出所有的rooms這樣一個很簡單的操作,也會查t整個rooms數(shù)據(jù)節(jié)點,返回所有的rooms下的數(shù)據(jù)節(jié)點到客戶端。使數(shù)據(jù)扁平化假設數(shù)據(jù)分布到不同的途徑下,那么就可以根據(jù)需要查詢最小化的數(shù)據(jù)量,大大進步查詢性能:“rooms數(shù)據(jù)節(jié)點下僅包含房間的根本信息和唯一ID。"rooms":&qu
52、ot;one":"name":"roomalpha","type":"private","two":.,"three":.,/room成員可以很方便的的存取"members":"one":"mchen":true,"hmadi":true,"two":.,"three":.,/消息數(shù)據(jù)與其他數(shù)據(jù)別分開,這樣我們在查詢其他數(shù)據(jù)時就不收消息數(shù)據(jù)的影響,
53、從而提升性能。/消息數(shù)據(jù)可以通過roomID方便的分頁和查詢。"messages":"one":"ml":"sender":"mchen","message":"foo","m2":.,"m3":.,"two":.,"three":.這樣組織數(shù)據(jù),就可以很方便的查詢room列表了,只需要傳輸很少的字節(jié)數(shù)。message數(shù)據(jù)也可以很容易的查詢。使數(shù)據(jù)可擴展很多時候需要查詢一個列表
54、的一個子集數(shù)據(jù),尤其是當這個列表中包含多達數(shù)千條或更多記錄時。當這個數(shù)據(jù)之間的關系是單向且數(shù)據(jù)比較穩(wěn)定的時候,我們可以簡單的把子節(jié)點數(shù)據(jù)嵌套到父節(jié)點之下:"users":"john":"todoList":"rec1":"Walkthedog","rec2":"Buymilk","rec3":"WinagoldmedalintheOlympics但很多時候數(shù)據(jù)頻發(fā)變化,或者有時候必須把數(shù)據(jù)拆分存儲到不同的途徑下John可能有一
55、個長達數(shù)千項的todo列表。通??梢杂毛@取數(shù)據(jù)中介紹的函數(shù)來查詢一個列表的子集。但僅僅如此可能還是不夠的??紤]一個例子,users和groups之間的雙向關系。user可以屬于group,group包含一個user列表。乍看之下數(shù)據(jù)可能這樣組織:"users": "mchen": "name":"brinchen": "name":"hmadi": "name":"Mary Chen" ,"Byambyn Rinchen&qu
56、ot; ,"Hamadi Madi" ,"groups":"alpha":"name":"AlphaTango"members":"m1":"mchen","m2":"brinchen""m3":"hamadi","bravo":.,"charlie":.看起來不錯。但是當需要判斷一個user屬于哪些group的時候,困難就來了
57、。我們可以在數(shù)據(jù)發(fā)生改變的時候遍歷并更新所有的group,但這樣做本錢很高,也很慢。更糟糕的是,假設Mary沒有權限查看所有的group時怎么辦呢?當查詢整個列表時,會得到一個沒有權限訪問的錯誤。我們需要的是一種優(yōu)雅的方式,可以列出Mary屬于哪些group,只需要查詢這些group就行了。數(shù)據(jù)可以這樣組織:"users":"mchen":"name":"MaryChen",/在Mary的數(shù)據(jù)下,建立他所屬group的索引。"groups":/這里的值是什么并不重要。重要的是這個子節(jié)點的key存
58、在。"alpha":true,"charlie":true,.,"groups":.我們把關系數(shù)據(jù)同時存儲在了Mary的記錄下和group數(shù)據(jù)下,這樣造成了數(shù)據(jù)的重復。假設要把Mary從一個組中刪除,就需要更新兩個地方。對于雙向的關系來說,這樣的冗余是有必要的。這樣做使我們可以很高效的查詢Mary的個人信息,即使users和groups都有百萬級的數(shù)據(jù),且規(guī)那么表達式制止訪問不相關的數(shù)據(jù)時。為什么我們把id作為key,而把value設置為true呢?這樣做是有好處的。這樣使得檢查一個id是否存在變得非常簡單,只需要讀取/users/m
59、chen/groups/$group_id,看它是否為null就可以了。/判斷Mary是否屬于alphagroupvarref=newWilddog("s:<appId>.wilddogio/web/org/users/mchen/groups/alpha");ref.once('value',function(snap)varresult=snap.val()=null?'isnot':'is'console.log('Mary'+result+'amemberofalphagroup);
60、);平安是一個非常重大的話題,通常也是app開發(fā)中最困難的部分之一。Wilddog使用一種聲明式的規(guī)那么表達式,對數(shù)據(jù)的訪問權限進展配置,讓這一切變得簡單。認證用戶ID是一個非常重要概念,不同的用戶擁有不同的數(shù)據(jù)和不同的權限,比方,在一個聊天程序中,每一條消息都有它的發(fā)布者,用戶可以刪除自己的消息,而不能刪除別人的。平安的第一步是用戶認證。Wilddog提供了以下終端用戶認證的方式:?集成微博,微信,QQ等社交平臺的OAuth認證?Email/密碼登錄,并且提供用戶管理?匿名用戶訪問?自定義token,方便用戶集成已有的用戶賬戶系統(tǒng)。授權知道用戶的身份只是平安的一部分,一旦你知道誰在訪問數(shù)據(jù),
61、你需要一種方式來控制訪問權限。Wilddog提供了一種聲明式的表達式語言,你可以在控制面板中的規(guī)那么表達式''tab下進展編輯這些規(guī)那么表達式讓你可以管理數(shù)據(jù)的訪問規(guī)那么。規(guī)那么級聯(lián)應用到其子節(jié)點。"rules":"foo":".read":true,".write":false這個例子允許所有人訪問數(shù)據(jù)節(jié)點fooo規(guī)那么表達式包含一系列內(nèi)置對象和函數(shù)。最重要的一個內(nèi)置對象是auth,它在終端用戶認證的時候生成,包含終端用戶的信息和用戶的唯一id:auth.uid。auth對象是很多規(guī)那么表達式的根
62、底。"rules":"users":"$user_id":".write":"$user_id=auth.uid"這個規(guī)那么保證了:只有終端用戶的唯一id等于動態(tài)途徑$user_id的值時,用戶才能寫入數(shù)據(jù)數(shù)據(jù)校驗規(guī)那么表達式中還包含一個.validate規(guī)那么,用于對數(shù)據(jù)進展校驗,確保數(shù)據(jù)的格式正確。它的語法和.read與.write一樣,不同的是.validate規(guī)那么不會向下級聯(lián)。"rules":"foo":".validate"
63、:"newData.isString()&&newData.val().length()<100"這一規(guī)那么確保了在/foo/節(jié)點下,寫入的數(shù)據(jù)必須是字符串類型,且必須長度小于100。.validate規(guī)那么可以使用的內(nèi)置對象和函數(shù)與.read和.write一樣。"rules":"user":".validate":"auth!=null&&newData.val()=auth.uid"這一規(guī)那么弓S迫使寫入/user/下的數(shù)據(jù)必須是當前登陸用戶的唯一id。.validate規(guī)那么并不是要徹底取消應用中的數(shù)據(jù)校驗代碼。為了獲得更好的性能和用戶體驗,你仍然必須在應用代碼中對數(shù)據(jù)進展校驗。理解更多到此為止,你應該對Wilddog中的應用平安機制有了一個大體的理解。規(guī)那么表達式是復雜且強大的,本開發(fā)向?qū)е兄缓w了非常小的一部分。更多關于規(guī)那么表達式的細節(jié),請參考規(guī)那么表達式文檔,這里將會講述所有的內(nèi)置函數(shù)和對象。絕大多數(shù)應用都需要一套終端用戶賬號體系。對終端用戶進展唯一標識之后,才能對用戶進展個性化的用戶體驗,控制用戶對數(shù)據(jù)的訪
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 二零二五年度水利工程項目投標擔保委托保證合同3篇
- 二零二五版葫蘆島市房屋繼承合同范本3篇
- 基于二零二五年業(yè)績目標的小型餐飲店面館飯店加盟合同3篇
- 二零二五年湖南機關事業(yè)單位合同制工人醫(yī)療保險聘用合同3篇
- 二零二五版電梯門套工程安全風險評估與應急預案合同3篇
- 二零二五年電子商務糾紛解決機制合同2篇
- 二零二五年度辣椒種植與農(nóng)業(yè)科技創(chuàng)新合作合同3篇
- 二零二五年度物流配送中心場地租賃合同BF06023篇
- 二零二五年度服裝調(diào)換貨及退貨處理合同范本3篇
- 二零二五年度酒店住宿代理服務合同示范文本2篇
- 經(jīng)方治療腦梗塞的體會
- 新版DFMEA基礎知識解析與運用-培訓教材
- 制氮機操作安全規(guī)程
- 衡水市出租車駕駛員從業(yè)資格區(qū)域科目考試題庫(全真題庫)
- 護理安全用氧培訓課件
- 《三國演義》中人物性格探析研究性課題報告
- 注冊電氣工程師公共基礎高數(shù)輔導課件
- 土方勞務分包合同中鐵十一局
- 乳腺導管原位癌
- 冷庫管道應急預案
- 司法考試必背大全(涵蓋所有法律考點)
評論
0/150
提交評論