前文構造的篩選器對象能夠實現簡單的欄位篩選,但是,實際應用中,我們常常會遇到對數組進行操作的需求,如果僅僅是對單純的數組進行檢索、定界、排序尚不複雜,而當數組資料混雜在更複雜的對象中或者數組中包含複雜物件時,這些需求就會變得比較棘手了。
數組篩選器就是應對這些問題而設計的,我們繼續從一個簡單的例子開始:
如下是一個很平常的數組對象:
[{ 'field1': 1, 'field2': 1, 'field3': 1, 'field4': 4 },{ 'field1': 1, 'field2': 2, 'field3': 4, 'field4': 1 },{ 'field1': 1, 'field2': 2, 'field3': 1, 'field4': 2 },{ 'field1': 2, 'field2': 1, 'field3': 2, 'field4': 3 },{ 'field1': 1, 'field2': 2, 'field3': 2, 'field4': 5 }]
現在針對這個數組,我們的需求如下:
將數組基於field3降序排序。 只保留field1欄位值為1的前2項。 最終的篩選結果中只保留field1和field4兩個欄位。
針對以上需求,按照常規方式我們會分三步對資料進行處理,預估的代碼量可能需要數十行,當需求發生改變時,往往會把這些代碼搞得一團糟,OK,我們用篩選器的思路來做做看,下面構造如下的篩選器:
[ 'field1', 'field4', [ { '$sort': [ '!field3' ] }, { '$filter': { 'field1': 1 } }, { '$limit': [ 0, 2 ] } ]]
在如上的篩選器中,依然是從欄位篩選開始(篩選器最外層數組中的每一項表示要保留的欄位),當欄位篩選的對象是數組時,篩選器會自動深入數組中對數組的每一項生效。
與前文不同的是,這個篩選器的第三項並不是描述欄位名的字串,而是又一個數組,這個數組就是所謂的數組篩選器。
數組篩選器目前可以包含三個可選的對象,分別是$sort,$filter和$limit。其中$sort對象實現對數組的排序,他的值是一個排序欄位的列表數組,數組中的每一項表示一個排序欄位,寫在前面的欄位名排序優先順序更高,此外在欄位名前加上!字元表示降序排列(預設為升序)。
$filter對象實現對數組欄位值的篩選(類似於SQL中的WHERE),他的值是一個對象,對象中的每一項表示一個篩選條件,如篩選器即表示選擇field1欄位值為1的項。目前篩選器僅支援完全符合,後續會加入Regex匹配以完善功能。
$limit對象實現對數組的水平裁剪,它的值是一個數組或一個數字,當值為數組時,數組的第一項表示裁剪的位移量,第二項表示裁剪的長度。當值為數字時,表示僅取數組的第n項。
數組篩選器可以放置在欄位篩選器的任意位置,實際上篩選器代碼總是會優先處理完數組篩選器後才會執列欄位篩選操作(垂直裁剪)。
以上篩選器最終會產生如下結果,與我們需求預想的結果一致:
[{ 'field1': 1, 'field4': 1 },{ 'field1': 1, 'field4': 5 }]
以上三個
數組篩選器配合上前文介紹的
欄位篩選器和
子欄位篩選器,實際上不經意間我們實現了一個簡單的記憶體資料庫(目前僅支援尋找,不支援更新)。