lit*_*ito 6 rethinkdb rethinkdb-javascript
链式有什么区别:
r.db('catbox').table("bw_mobile").filter(
r.row("value")("appVersion")("major").le(2)
).filter(
r.row("value")("appVersion")("minor").le(2)
).filter(
r.row("value")("appVersion")("patch").le(10)
)
Run Code Online (Sandbox Code Playgroud)
嵌套:
r.db('catbox').table("bw_mobile").filter(
r.row("value")("appVersion")("major").le(2).and(
r.row("value")("appVersion")("minor").le(2).and(
r.row("value")("appVersion")("patch").le(10)
)
)
)
Run Code Online (Sandbox Code Playgroud)
或 lambda 函数
r.db('catbox').table("bw_mobile").filter(
r.js("(function (session) {
return session.value.appVersion.major < 0
|| ( session.value.appVersion.major == 0 && session.value.appVersion.minor < 0 )
|| ( session.value.appVersion.major == 0 && session.value.appVersion.minor == 0 && session.value.appVersion.patch < 71 )
;
})")
)
Run Code Online (Sandbox Code Playgroud)
泰!
我认为第二种情况(单个filter有多个and表达式)是最高效、最方便使用的。我会考虑以下想法:
r.filter正如记录的那样,无论传递给 的谓词函数的结果如何,总是r.filter创建一个新的选择、一个流或一个数组。我不确定 RethinkDB 中如何实现选择(我相信它们是类似流的),但数组链接可能是分配中间数组的昂贵操作。将此与Array.prototype.filter创建一个新数组作为结果进行比较。流是惰性的,因此每个元素也被延迟计算(或不延迟计算),从而产生更小的内存占用。将此与其他语言中的迭代器/流和生成器(Java 中的Iterator<E>/和.NET/C# 中的 /,JavaScript 中的迭代器和生成器函数,Python 中的迭代器和生成器函数,shell 命令中的管道等)进行比较,您可以在其中组合迭代器/生成器。无论如何,你都有中间过滤器。Stream<E>IEnumerator<T>yield returnyield|
单个表达式可以代替一堆链式过滤器操作。请注意,r.and表达式中的操作有一个非常重要的特征:这是一种短路求值操作。如果 AND 运算的左侧操作数是false,则该运算甚至不需要计算右侧表达式即可获得始终为falsethen 的结果。你不能用 做这样的事情r.filter。将此与每个单个查询可以指定一次的 SQL WHERE 子句进行比较(所有错误情况都可以由AND运算符简单地丢弃)。此外,从实用的角度来看,您可以创建一个工厂方法,该方法可以具有方便的名称并返回参数化的 ReQL 表达式,甚至可以将其分配给常量,因为 ReQL 表达式是不可变的并且可以安全地重用:
const maxVersionIs = (major, minor, patch) => r.row("value")("appVersion")("major").le(major)
.and(r.row("value")("appVersion")("minor").le(minor))
.and(r.row("value")("appVersion")("patch").le(patch));
const versionPriorToMilestone = maxVersionIs(2, 2, 10);
...
.filter(maxVersionIs(major, minor, patch))
...
.filter(versionPriorToMilestone)
Run Code Online (Sandbox Code Playgroud)
ReQL 表达式 RethinkDB 查询实际上是表达式树,比执行 JavaScript 脚本更容易解析并直接转换为执行计划。官方文档甚至建议避免使用r.js以获得更好的性能。我猜这里的成本是 JavaScript 运行时设置、独立的脚本执行和检查脚本超时。此外,脚本更容易出错,而表达式树可以在编译期间或多或少地进行检查。但是,为了完整起见,r.js即使有这些成本,也可以更强大,因为 ReQL 是一组有限的操作。从我个人的经验来看:我必须实现一种基于 RethinkDB 的权限检查子系统,并且我需要在 RethinkDB 中进行按位 AND 运算。不幸的是,RethinkDB 从 2.3 开始不支持按位运算,所以我不得不使用r.js: r.js('(function (user) { return !!(user.permissions & ${permissions}); })')。RethinkDB 的未来版本将支持按位运算,因此r.getField('permissions').bitAnd(permissions))将来的某一天应该会更快地工作,并且可以与其他表达式组合以适应单个filter.
| 归档时间: |
|
| 查看次数: |
218 次 |
| 最近记录: |