Notion 最近上線了 Formula 2.0,帶來了多項新特性和函數,顯著提升了公式的易用性和可讀性。
新版本去掉了 prop() 的固定格式,支援程式碼換行與註解,新增了四個預設欄位和一系列陣列處理函數。透過全新的寫法 Dot-notation,使用者可以更簡潔地書寫和閱讀公式,優化了資料處理流程。
這些更新使 Notion 在資料管理和公式處理上更加強大,為使用者提供了更高效的工作體驗。
以下是閱讀本文需要知悉的一些注意事項:
- 本文所解析的功能細節以 Notion 官方發佈的這篇 文章 為參考
- 閱讀本文需要具備一定的 Formula 1.0 使用經驗,否則可能難以領會 2.0 的更新要點
細節變化
去掉了 prop() 的函數格式
在 Formula 1.0 中,每個欄位都需要帶上 prop() 的固定格式,於是當你的公式寫得複雜,過長的函數格式就會使得閱讀體驗急劇下降。
Formula 2.0 去除了 prop() 後就能非常直觀地讓公式縮短,極大提升了可讀性。
不過需要注意的是,當你複製這串新的 Formula 並貼上於別處(例如 Code block),則會發現貼上的文字中依然帶有 prop() 的格式:
if(and(or(prop("任务状态") == "Not started", prop("任务状态") == "In progress"), prop("剩余时间") <= 0), "😡 已逾期", if(and(or(prop("任务状态") == "Not started", prop("任务状态") == "In progress"), (prop("剩余时间") > 0) and (prop("剩余时间") <= 7)), "😱 即将逾期", "🤗 状态正常"))也因此,本文所展示的諸多函數都將繼續帶有 prop() 的固定樣式。
支援程式碼換行與註解添加
現在的編輯器終於支援換行和添加註解了,這使得公式的書寫更加便利,不會寫著寫著就迷失在各種括號之中。
now() /* 獲取當前日期 */
.dateAdd(1,"days") /* 在當前日期的基礎上增加 1 天*/換行的方式為 Shift+回車鍵,添加註解的方法則是用 /* 與 */ 將註解文字包圍起來即可。
更快顯示計算結果與更直觀的錯誤提示
現在的編輯器會在函數下方即時顯示計算結果,這樣能讓你更快地判斷函數書寫正確與否。
如果書寫錯誤,它也會出現更加直觀易讀的錯誤提醒。
新增撤銷按鈕
當我們對現有的公式進行編輯,但編輯結果出現錯誤的時候,現在可以直接點擊右上角的 Revert 按鈕,來將所有的操作進行復位。
全新函數寫法 Dot-notation
在 Formula 1.0 中,如果我們想實現諸如「計算特定日期與今天的天數差」,則需要這麼寫:
dateBetween(now(),prop("Date"),"days")如果你想繼續將計算得出的天數轉換為字串,則需要再用 format() 將其包括在內:
format(dateBetween(now(),prop("Date"),"days"))+ "" + "天"以上是傳統的函數呼叫寫法,當函數一長,就會出現無數個括號,我們就總是會因為漏寫了哪一個括號而需要花半天時間去排查,在閱讀的時候又需要先去找括號,才能找到正確的閱讀順序。
不過現在我們可以在 Formula 中使用如下所示的全新寫法:
now().dateBetween(prop("Date"),"days").format()這項更新幾乎徹底改變了 Formula 的寫法與閱讀順序:
- 最左邊的
now()表示我們要進行操作的對象 - 其後的
.dateBetween()函數表示我們要對now()進行日期間隔計算 - 最後的
.format()表示我們要對前一步的計算結果進行字串轉換
結合可換行的特性,這樣函數就變得更加易讀了:
now() /* 獲取當前時間 */
.dateBetween(prop("Date"),"days") /* 與 Date 欄位的時間進行計算 */
.format() /* 將上一步的計算結果轉換為字串 */
+" " + "天" /* 拼接字串 */now()
.dateAdd(1,"weeks") /* 將今天的日期加上 1 週時間 */
.format() /* 將日期計算結果轉換成字串 */新增四個預設欄位
現在 Notion 在編輯器中內建了四個預設欄位,分別是:
- Created By、建立者
- Created Time、建立時間
- Last Edited By、最近一位編輯者
- Last Edited Time、最近一次編輯時間
這樣一來當我們需要用到這些欄位的時候,就不用再特意新建一個欄位了。
鑒於 Created By 與 Last Edited By 都與某個 Member 有關,所以我們還可以用 .name() 或者 .email() 這兩個函數來直接返回建立者(或編輯者)的姓名或信箱。
所以,如果你將 Notion 用於團隊協作,並且同一個資料庫會有多人參與編輯,就可以用這些預設的內建欄位來即時顯示編輯者的名字、信箱或者編輯時間等操作。
日期函數調整
dateStart 與 dateEnd
在 Formula 1.0 中,如果我們想從一個範圍日期中獲取它的開始時間或者結束時間,其函數寫法是 Start() 或者 end(),不過現在這兩個函數被重新命名為 dateStart() 與 dateEnd()。
month、week、day
- 現在
month()函數會返回從 1-12 的值,在 Formula 1.0 中則是 0-11;例如現在是 11月,則month(now())將返回數字 11; - 現在
day()函數會返回從 1-7 的值,在 Formula 1.0 中則是 0-6;例如現在是星期三,則day(now())將返回數字 3 week(now())將返回當前時間是一年中的第幾週,例如現在是 11 月 6 號,則week(now())將返回數字 44
新增函數
陣列
在 Formula 1.0 中,公式結果只支援輸出文字、數值以及布林值這三種,但現在 Formula 還能夠以**列表(陣列)**形式輸出結果。
如果我們在陣列的基礎上 +1,則輸出的所有數值都會 +1。
使用 sort() 函數可以對陣列進行排序。
使用 reverse() 函數可以對排序後的陣列進行倒序處理。
除了數字排序,還支援英文首字母排序。
使用 at() 函數可以輸出指定位數的對象(0 為第一個,1 為第二個)。
使用 first() 或者 last() 分別獲取首位或者末尾對象。
使用 unique() 函數去除陣列中重複的值,輸出唯一值。
使用 includes() 函數判斷陣列中是否存在指定的對象,存在則為 true,否則 false。
使用 slice() 函數則能從陣列中切割出指定數量的對象。
除了數字陣列外,我們還可以在 Formula 中選中人員(Person)、多選(Multi-select)以及關聯頁面(Relation)等欄位,Formula 將直接以陣列的形式輸出這些欄位。
因為輸出的是陣列,所以上述提及的所有函數如 sort()、reverse()、includes() 都是可以應用在這些欄位上的。
例如我們還可以用 length() 這個函數來快速計算陣列中的對象數量。
透過這個方法我們可以用 Person 這個欄位來統計投票數。
或者用於統計 Multi-select 的選擇個數。
以上僅是陣列的一些基礎特性,後面的內容還會介紹更多可供參考的函數與用法。
map
Map 這個函數的基礎表達式是 map(list, expression),它能接收一個列表(陣列),然後透過你自訂的表達式的處理來返回另一個列表。
以官方提供的案例為例:
map([1, 2, 3], current + 1)
= [2, 3, 4]我們來逐個解析這串公式:
[1,2,3]是我們給定的一個陣列current用於返回當前陣列元素,+1則是在其基礎上增加數值 1[2,3,4]則是透過map這個函數最終返回的結果
接下來我們嘗試用 map 函數來讀取 Relation 這個欄位,並且表達式僅為 current,則這個函數將原封不動地返回 Relation 欄位所關聯到的頁面列表。
如果在 current 後面添加一個點 .,map 函數就能夠讀取並輸出頁面中的特定欄位資訊,例如選取 Status 欄位,於是 map 函數就返回了所有任務(頁面)的當前狀態。
如果選擇的是 Number(成本)這個欄位,則 map 函數會返回所有頁面的成本欄位。
基於陣列的特性,我們就可以再使用 min() 或者 max() 函數,然後從中獲取成本最少或者最多的那一項,這就是 map 函數的最基礎用法。
filter
在 filter() 這個函數的幫助下,我們無需建立 Rollup 欄位,就可以直接用 Formula 來對 Relation 進行快捷的篩選操作。
在 PARA 個人知識庫的搭建方法中,在其理論基礎上我們會將領域與項目進行關聯,例如二級領域「筆記軟體測評」就使用 Relation 這個欄位關聯到了數個測評項目上。
但是隨著時間的增長,領域所關聯的項目一定會越來越多,而這個欄位也會變得越來越擁擠,直到關聯個數超過 10 個後,就會將其餘欄位摺疊起來。
所以這個時候我們就可以利用 filter() 這個函數來對 Relation 欄位進行篩選,如果我希望篩選出那些未完成的項目(即 Status 不為 Done),那麼這個函數的寫法如下:
prop("关联项目").filter(current.prop("Status") !="Done")從左往右閱讀這串函數,其含義依次是:
- 正在進行操作的欄位是
prop("关联项目") - 操作的方式是使用
.filter()這個函數對它進行過濾 - 過濾方式是使用
current這個變數來獲取prop("关联项目")的 Status 欄位 - 最後從中篩選出所有狀態不為 Done 的條目(
!=的含義是不等於)
同樣的,如果我希望從中篩選出「負責人是 A 的項目」,那麼函數的寫法如下:
prop("关联项目").filter(current.prop("负责人") == "A")再加上 length() 函數,就能透過計算陣列所包含的對象的個數來統計出符合篩選條件的個數。
parseTime
在 Formula 1.0 中,如果我們希望能指定一個自訂的日期,則實現的方式相當麻煩,需要先將日期轉換為 Unix 時間戳,然後再利用 fromTimestamp() 這個函數將時間戳轉換為可供閱讀的日期格式才行,過程非常的繁瑣。
不過現在我們可以使用 parseTime() 這個函數來快捷地輸入任意日期:
parseDate("2023-10-29")但預設情況下返回的日期格式有可能不太符合預期,所以我們可以繼續用 formatDate() 函數來指定你希望的格式:
parseDate("2023-10-29").formatDate("YYYY-MM-DD")透過 parseDate() 所自訂的日期就可以參與到 dateBetween() 等日期函數的計算之中了。
let 和 lets
在一些複雜的函數計算中,我們經常遇到需要重複取用同一個計算結果,但這個計算結果又需要透過一串較長的公式才能得出,這就可能導致完整的函數書寫中,這串長長的公式需要重複出現多次,使得完整的函數變得冗長且難以閱讀。
舉一個簡單的例子,在 Formula 1.0 中,假設我們有一個「銷售業績資料庫」,其中包含 目標銷售額、實際銷售額 這兩個欄位,並且在後續的一系列業績抽成中,我們需要圍繞 實際銷售額/目標銷售額 所得出的 銷售額完成率 來進行計算,這就使得 實際銷售額/目標銷售額 需要在函數書寫中反覆出現。
當然我們確實可以再建立一個欄位,單獨求出其銷售完成率。
但隨著 let() 和 lets() 這兩個新函數的出現,今後我們有了全新的解法。這兩個函數都能允許你在計算中自訂區域變數,以此減少重複的函數、提高整體可讀性。
let() 函數的基本結構是:let(variable, value, expression),官方給定的例子如下:
let(name, "Doug Engelbart", "Hello, " + name + "!")
= "Hello, Doug Engelbart!"這裡定義了一個名為 name 的變數,並賦值為 "Doug Engelbart"。然後在後續的計算中,我們就能直接使用這個變數 name 來構造一句問候語。
另外,這個例子中出現的人名 Dough Engelbart 其實是 Notion 官方所留下的一個彩蛋,這是一位對 Notion 這款產品的開發歷程產生了極其深遠影響的學者。
lets() 函數的基本結構是:lets(variable, value, variable2, value2, ..., expression),官方給定的例子如下:
lets(a, "Hello", b, "world", a + " " + b)
= "Hello world"這裡定義了兩個變數:a 和 b,分別賦值為 "Hello" 和 "world",然後使用這兩個變數構造了一個簡單的句子。
所以讓我們回到本段開頭的問題,為了避免 實際銷售額/目標銷售額 在函數中反覆出現,我們就可以用 let() 函數自訂一個名為「銷售完成率」的變數,並將其賦值為 實際銷售額/目標銷售額,然後規定當銷售完成率大於 1,則獎金 1000 元,小於 1 則沒有獎金:
let(
销售完成率,prop("实际销售额")/prop("目标销售额"), /*定義銷售完成率*/
if(prop("销售完成率")>1,1000,0) /*根據不同的銷售完成率,返回不同的獎金數*/
)ifs
在 Formula 1.0 關於 if() 函數的書寫中,有一個非常讓人頭疼的問題就是很容易漏掉多個條件巢狀的括號,例如在下面的績效薪資計算中,不同的績效評級對應了不同的薪資倍率,於是我們的 if 函數就得這麼寫:
if(prop("年终评级") == "不合格", prop("基础工资") * 0.8,
if(prop("年终评级") == "合格", prop("基础工资") * 1,
if(prop("年终评级") == "良好", prop("基础工资") * 1.1,
if(prop("年终评级") == "优秀", prop("基础工资") * 1.2, prop("基础工资") * 1.5))))但是隨著 ifs 函數的加入,我們可以將整個函數簡化成這樣:
ifs(
prop("年终评级") == "不合格", prop("基础工资") * 0.8,
prop("年终评级") == "合格", prop("基础工资") * 1,
prop("年终评级") == "良好", prop("基础工资") * 1.1,
prop("年终评级") == "优秀", prop("基础工资") * 1.2,
prop("基础工资") * 1.5
)全程只要用逗號將不同的條件隔開即可,並且最終也只需要一個括號即可,使得書寫和閱讀體驗大大提高。
Style
在 Formula 1.0 中,如果我們希望對輸出的文字進行一點修飾,則最多只能用一些 emoji 符號。
但現在 Notion 推出了 style 函數,這讓我們可以自由地指定字串的字體顏色、字體背景色、是否加粗等特性。
Style 的用法也非常簡單,如果要實現加粗效果的話,只需要在字串後面使用 .style("b") 即可。
在 Formula 提示框中,官方一共提供了以下幾種格式:
- "b":粗體
- "i":斜體
- "u":底線
- "c":程式碼
- "s":刪除線
同時可用的字體顏色包括:
- gray:灰色
- brown:棕色
- orange:橙色
- yellow:黃色
- green:綠色
- blue:藍色
- purple:紫色
- pink:粉色
- red:紅色
如果你想添加的是字體的背景顏色,則只需要在顏色的後面添加 _background 的後綴即可。
尾聲
至此,本次 Formula 2.0 的基礎解析就暫告結束了。如果你想看看這些新函數在實際場景中的應用,推薦閱讀任務狀態提示終極版和用函數變數構建間隔重複任務這兩篇教程。Notion 後續還新增了 today、median、mean 三個實用函數。我非常期待 Notion 下一次的大更新還將給我們帶來怎樣新的變化,届時我也將第一時間與各位讀者分享,那麼就讓我們下一篇文章再見吧,感謝大家的支持!
📘 FLO.W 思流 — Notion 個人管理系統
FLO.W 是一套基於 Notion 搭建的個人管理模板,整合了任務、筆記、項目、習慣等模組,並配有完整的圖文影片教程。







