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 下一次的大更新还将给我们带来怎样新的变化,届时我也将第一时间与各位读者分享,那么就让我们下一篇文章再见吧,感谢大家的支持!
📘 FLO.W 思流 — Notion 个人管理系统
FLO.W 是一套基于 Notion 搭建的个人管理模板,整合了任务、笔记、项目、习惯等模块,并配有完整的图文视频教程。


