開發者對複雜的數據結構的處理能力也是體現開發者水平的一個度量吧。。。最近發現本身對一些嵌套數據結構、層級數據結構的處理能力不大足。。。常常被這些把本身繞暈。。。嚴重影響開發效率。。。就稍微低總結了一下下。。。javascript
1、mongodb設計層級關係數據(這裏主要說的是mongoose)vue
①假設有這樣的一個場景。某個文章下面有評論,每一個評論能夠被回覆,每一個回覆又能夠被回覆...java
首先,咱們知道,普通的一對多的關係,能夠經過引用,populate操做找出相應的引用對象,如:node
var essaySchema = new mongoose.Schema({ //文章schema user:{ type: mongoose.Schema.Types.ObjectId, //發佈者的引用 ref: 'user', //引用自User Model require: true //非空 }, ... });
文章與評論的關係,就是一對多。天然也是按照這種處理方式便可。git
可是,評論與回覆的關係,就有點意思了。首先,評論和回覆,回覆與該回復的回覆雖然是不一樣的東西(看着就拗口),可是這些的shema的信息都是由相同的字段構成。也就是說,能夠說是本身嵌套了多個本身。github
這個時候,就要這樣處理了:mongodb
//評論Schema定義 var commentSchema = new mongoose.Schema({ content: { type: String, require: true }, created: { type: Date, "default": Date.now }, user: { type: mongoose.Schema.Types.ObjectId, //用戶的引用 ref: 'user', //引用自User Model require: true //非空 }, subComment: [this], //自評論的類型爲評論類型,也就是自己類型 });
最關鍵就是最後一句,實質上就是遞歸地引用了自身。查找的時候,也確實是須要根據上一層的subComment找到本身。套了深層的時候,查找的時候會容易繞暈,並且查找速度也會下降。建議作層級限制。express
實踐小項目:一個簡單版node+express+mongodb的圖片分享api
2、實際開發場景中的層級關係數據數組
①假設有這樣的一個場景,有一個商品數組,每一個商品有兩個維度,顏色和規格。顏色和規格的組合會產生的sku(能夠理解爲每種組合狀況的一個標識)數量爲顏色數量*規格數量。當咱們渲染完畢以後,顧客每切換一個規格,都要找到相應的sku。
設想一下,假如顧客每切換一個規格,咱們就根據第幾個商品,切換的規格,沒有被切換的規格去查找。那麼每次都是一個三重循環。。。
這種狀況下,比較好的作法就是,初始化得到數據的時候,創建三維數據,即Array[商品index][顏色][規格]。這樣每次切換,只要讀取相應的項就能夠找到sku了。
可是,倘若商品的維度不是二維,而是多維呢,並且不必定每種組合都存在這樣的商品的呢?
構造數據的方法,就顯得不大明智了,一是組合數過多,並非每種組合商品都存在,而是循環太多重。
這個時候,又要利用對象去構造數據了。
第一步,根據展現須要構造。展現的時候,只須要知道,某個商品的某個維度是某個值便可。即:
var obj = {[ {'商品':'1',sku:'','維度1’:'...','維度2':'...',...} ]}
當點擊切換維度的時候,首先根據原來的維度信息,更新用戶新選的維度。遍歷該新的維度對象,與維度信息數據比較,若是一一相符則找到新的sku。而後再更新便可。
在這裏就要明確本身的"籌碼"與"目標",根據哪些東西,經過哪些途徑能夠到達目標。將每一步拆分紅一個小方法去作。。。
②假設有這樣的一個場景,首先要根據一些規則合併一些請求去請求不一樣的數據(即返回的數據,是多個參數結合在一塊兒的,必須還要解析出數據原先的對應關係),而後得到部分數據。再用得到的部分數據中某條數據的參數去請求第二個接口。而後得到不一樣的一些數據。
首先想到的多是用promise處理,待兩個接口都請求完畢後再進行處理。可是假如,第一個接口得到的是大部分主要的數據,第二個是小部分的數據。這個時候,等待第二個接口彷佛就有點"不划算"了,特別是在用戶體驗上,當一個用戶打開某個頁面的時候,白屏就很差啦。
這個時候,咱們就要善於利用對象去構造符合咱們的數據對象了。
咱們能夠這樣初始化一個對象:
var obj = { '惟一的參數1'+‘_’+'惟一的參數1的id' : { 第一次請求的數據 : [], 第二次請求的數據 : [], }, '惟一的參數2'+‘_’+'惟一的參數2的id' : { 第一次請求的數據 : [], 第二次請求的數據 : [], }, ... }
總之,就是要找到惟一的東西,來構造對象。而後再根據這個惟一的值把相應的數據填上。好吧,我都說暈了。看個例子:
for(var i = 0;i < data.length; i++){ for(var j = 0;j < data[i].params.length; j++){ obj[data[i].groupId + '_' + data[i].params[j].pcId] = {}; } } //請求數據回來後 for(var i = 0;i < data.length; i++){ for(var j = 0;j < data[i].params.length; j++){ obj[data[i].groupId + '_' + data[i].params[j].pcId][firstItem] = data[i].params[j].list; } } //第二次數據回來後 for(var i = 0;i < data.length; i++){ for(var j = 0;j < data[i].params.length; j++){ obj[data[i].groupId + '_' + data[i].params[j].pcId][moreItem] = data[i].params[j].list; } }
注意,若是是用vue,由於第二次請求的數據參數來自第一次,因此請二次數據回來以後,須要用全局api,set方法處理纔會生效。
好吧。。。說了那麼多,或許我本身明白本身在說啥。。。手動苦笑。。。