クエリでこの種の制約が必要な場合は、MongoDBのバージョンがサポートするものに応じて、基本的に2つのオプションがあります。
MongoDB 3.6
$ expr
を使用することをお勧めします。
「さらに」 有効なドキュメントを実際に選択するための通常のクエリ条件:
var A = 10, B = 40;
Model.find({
"subDocs.value": { "$all": [A, B] },
"$expr": {
"$lt": [
{ "$arrayElemAt": [
"$subDocs.index",
{ "$indexOfArray": [ "$subDocs.value", A ]}
]},
{ "$arrayElemAt": [
"$subDocs.index",
{ "$indexOfArray": [ "$subDocs.value", B ]}
]}
]
}
})
または、「最後の」と一致します 発生:
Model.find({
"subDocs.value": { "$all": [A, B] },
"$expr": {
"$lt": [
{ "$arrayElemAt": [
"$subDocs.index",
{ "$subtract": [
{ "$subtract": [{ "$size": "$subDocs.value" }, 1 ] },
{ "$indexOfArray": [ { "$reverseArray": "$subDocs.value" }, A ] }
]}
]},
{ "$arrayElemAt": [
"$subDocs.index",
{ "$subtract": [
{ "$subtract": [{ "$size": "$subDocs.value" }, 1 ] },
{ "$indexOfArray": [ { "$reverseArray": "$subDocs.value" }, B ] }
]}
]}
]
}
})
以前のバージョン
同じことですが、ネイティブ演算子がない場合は、<のJavaScript評価を使用する必要があります。 code> $ where :
var A = 10, B = 40;
Model.find({
"subDocs.value": { "$all": [A, B] },
"$where": `this.subDocs.find( e => e.value === ${A}).index
< this.subDocs.find( e => e.value === ${B}).index`
})
または、「最後の」と一致します 発生:
Model.find({
"subDocs.value": { "$all": [10,40] },
"$where": `let arr = this.subDocs.reverse();
return arr.find( e => e.value === ${A}).index
> arr.find( e => e.value === ${B}).index`
})
集計パイプラインでそれが必要な場合は、を使用します。 $ redact
代わりに、最初の例と同様のロジック:
var A = 10, B = 40;
Model.aggregate([
{ "$match": { "subDocs.value": { "$all": [A, B] } } },
{ "$redact": {
"$cond": {
"if": {
"$lt": [
{ "$arrayElemAt": [
"$subDocs.index",
{ "$indexOfArray": [ "$subDocs.value", A ]}
]},
{ "$arrayElemAt": [
"$subDocs.index",
{ "$indexOfArray": [ "$subDocs.value", B ]}
]}
]
},
"then": "$$KEEP",
"else": "$$PRUNE"
}
}}
])
「比較ロジック」は実際には「クエリ演算子式」自体に固有のものではないため、「最適に」ある唯一の部分であると言えば十分です。 インデックスに適用できるのは、 $ all コード>
すべての場合のクエリ演算子。残りの重要なロジックは、実際には、主な式が評価された後、および「に加えて」適用され、 $ expr
または $ where
。
それぞれの基本的なロジックは、基本的に "index"
の値を抽出することです。 "value"
のそれぞれの値と実際に一致する"first"配列メンバーのプロパティ 財産。これが「未満」の場合、条件は true
これにより、返されるドキュメントが満たされます。
したがって、「計算された評価」はクエリ演算子の効率と一致し、「インデックス」にアクセスできる他のクエリ演算子条件と「組み合わせて」使用されることなく、「フルコレクションスキャン」が開始されることに注意してください。
ただし、全体的な結果は、一致するすべてのアイテムを最初のクエリ条件に戻し、データベースから戻った「後」にカーソルでそれらを拒否するよりも確かに効率的です。
$ arrayElemAt
のドキュメントも参照してください。
、 $ indexOfArray
、 $ lt
および Array.find()
JavaScriptの場合