連鎖の間に違いはありますか?
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)
)
)
)
またはラムダ関数
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!
2番目のケース(filter
複数のand
式を持つ単一)が最も効率的で最も使いやすいと思います。私は次の考えを考慮に入れます:
r.filter
、文書化されているように、に渡された述語関数の結果に関係なく、常に新しい選択、ストリーム、または配列を作成しr.filter
ます。RethinkDBで選択がどのように実装されているかはわかりませんが(ストリームのようなものだと思います)、配列の連鎖は、中間配列を割り当てるコストのかかる操作になる可能性があります。これをArray.prototype.filter
、結果として新しい配列を作成するものと比較してください。ストリームはレイジーであるため、各要素もレイジーに計算される(またはされない)ため、メモリフットプリントが小さくなります。(他の言語のイテレータ/ストリームと発電機とこれを比較Iterator<E>
/ Stream<E>
Javaで、IEnumerator<T>
およびyield return
.NET / C#、JavaScriptでイテレータとジェネレータ機能、にyield
Pythonで、パイプ|
シェルコマンドで。など)イテレータ/ジェネレータを組み合わせることができる場所。いずれにせよ、中間フィルターがあります。
単一の式で、一連の連鎖フィルター操作を置き換えることができます。r.and
式の操作には、非常に重要な機能が1つあることに注意してください。これは、短絡評価操作です。AND演算の左側のオペランドがである場合、演算はfalse
右側の式を評価する必要さえなく、常にそのような結果を得ることができますfalse
。でそんなことはできませんr.filter
。これを、単一のクエリごとに1回指定できるSQL WHERE句と比較してください(すべてのfalseケースは、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スクリプトを実行するよりも、解析がはるかに簡単で、実行プランに直接変換できる式ツリーです。公式ドキュメントでは、パフォーマンスを向上させるために使用を避けることも推奨さr.js
れています。ここでのコストは、JavaScriptランタイムのセットアップ、分離されたスクリプトの実行、およびスクリプトのタイムアウトのチェックだと思います。さらに、スクリプトはエラーが発生しやすくなりますが、式ツリーはコンパイル時に多かれ少なかれ検査される可能性があります。しかし、完全を期すために、r.js
ReQLは限られた一連の操作であるため、これらのコストがあってもより強力になる可能性があります。私の個人的な経験から:RethinkDBに基づく一種の権限チェックサブシステムを実装する必要があり、RethinkDBでビット単位のAND演算を行う必要がありました。私が使用していたので、残念ながら、2.3のようRethinkDBは、ビットごとの演算をサポートしていませんr.js
:r.js('(function (user) { return !!(user.permissions & ${permissions}); })')
。RethinkDBの将来のリリースではビット演算がサポートされるためr.getField('permissions').bitAnd(permissions))
、将来的にはより高速に動作し、他の式と組み合わせて1つに収まるようにする必要がありfilter
ます。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加