链接之间有什么区别:

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)
)

嵌套:
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)
        )
      )
)

或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 )
        ;
    })")
)

TY!

最佳答案

我认为第二种情况(带有多个filter表达式的单个and)是最有效和最方便的使用方式。
我会考虑以下几点:
r.filter就像documented一样,总是创建新的选择,流或数组,而不管谓词函数的结果传递给r.filter
我不确定RethinkDB中的选择如何实现(我相信它们像流一样),但是数组链接可能是分配中间数组的昂贵操作。
将此与Array.prototype.filter进行比较,它会创建一个新数组作为其结果。
流是惰性的,因此每个元素的计算也是(或不是)惰性的,因此占用的内存较小。
将其与其他语言的迭代器/流和生成器(Java中的Iterator<E>/Stream<E>,.NET/C#中的IEnumerator<T>yield return,JavaScript中的迭代器和生成器函数,Python中的yield, shell 程序命令中的管道|等进行比较)迭代器/生成器。
无论如何,您都有中间过滤器。

单个表达式可以代替一堆链接的过滤器操作。
请注意,表达式中的r.and操作具有一个非常重要的功能:这是短路评估操作。
如果AND操作的左侧操作数为false,则该操作甚至不需要评估右侧表达式即可获得始终为false的结果。
您不能使用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)

ReQL表达式RethinkDB查询实际上是表达式树,比执行JavaScript脚本更容易解析和直接转换为执行计划。
甚至recommends的官方文档也避免使用r.js以获得更好的性能。
我想这里的代价是JavaScript运行时设置,隔离的脚本执行以及检查脚本超时。
此外,脚本更容易出错,而在编译期间可以或多或少地检查表达式树。
但是,出于完整性考虑,即使RetL是有限的一组操作,r.js甚至可能会更强大,因为这些开销。
从我的个人经验来看:我必须实现一种基于RethinkDB的权限检查子系统,并且我需要在RethinkDB中进行按位AND操作。
不幸的是,从2.3版本开始,RethinkDB不支持按位操作,因此我不得不使用r.js:r.js('(function (user) { return !!(user.permissions & ${permissions}); })')
RethinkDB的 future 版本将支持bitwise operations,因此r.getField('permissions').bitAnd(permissions))应该在将来的某一天更快地运行,并且可以与其他表达式组合以适合单个filter

关于rethinkdb |嵌套查询与链接查询有什么区别?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/49307180/

10-12 19:38