このことから、我々は、2つの可能な結果を推測することができます
あなたの目的にのみすべて配列エントリが条件を満たした文書を返すことです。
「ドキュメント内の配列」のエントリを「フィルタリング」するのは、条件を満たす結果のみを返すことです。
これらからさまざまなアプローチがあります。まず、実際にMongoDBのためのクエリ演算子が存在しないということです。これは、 "すべての"配列要素が "通常のクエリ"で指定された条件を満たす必要があることを要求します。したがって、ロジックを別の形式で適用する必要があります。
このようなオプションの1つは、$where
のJavaScript評価を使用して、配列の内容を検査する方法です。ここでは、あなたの条件をテストするためにArray.every()
を適用することができます。これは実際にはいくつかの有用な作業を行っているので、通常のクエリフィルタに加えてです。
考えると、ソースドキュメントのように:
db.myCollection.find({
"explicitMods": /\d+ to \d+/,
"$where": function() { return this.explicitMods.every(e => /\d+ to \d+/.test(e)) }
}
})
のみを返します。
あなたの意図は、「すべて」の配列要素にマッチする「文書」を返すことだけです /* 1 */
{
"_id" : ObjectId("5993a35be38f41729f1d6501"),
"name" : "string",
"explicitMods" : [
"+48 to Blah",
"-13% to Blah",
"12 to 18 to Blah"
]
}
/* 2 */
{
"_id" : ObjectId("5993a35be38f41729f1d6502"),
"name" : "string",
"explicitMods" : [
"12 to 18 to Blah"
]
}
、次の文を発行一致する文書:
{
"_id" : ObjectId("5993a35be38f41729f1d6502"),
"name" : "string",
"explicitMods" : [
"12 to 18 to Blah"
]
}
を使用する代替の場合では、MongoDBの集約フレームワークでは、一般にJavaScriptの解釈式よりも高速に適用される「ネイティブコード演算子」を使用した式が使用できます。しかし実際には、$redact
などの集計操作に適用可能な$regex
の同等の「論理演算子」(SERVER-11947を参照)は存在しません。
したがって、ここで使用可能な唯一のアプローチは、配列要素が$unwind
を使用して、非正規化されている「後」ではなく、通常のクエリ条件で$match
を使用することです:
db.myCollection.aggregate([
// Match "possible" documents
{ "$match": { "explicitMods": /\d+ to \d+/ } },
// unwind to denormalize
{ "$unwind": "$explicitMods" },
// Match on the "array" items now as documents
{ "$match": { "explicitMods": /\d+ to \d+/ } },
// Optionally "re-group" back to documents with only matching array items
{ "$group": {
"_id": "$_id",
"name": { "$first": "$name" },
"explicitMods": { "$push": "$explicitMods" }
}}
])
そして、その1が返され、「両方」の文書が、わずかまします配列項目が一致するものが挙げられる。もちろん
/* 1 */
{
"_id" : ObjectId("5993a35be38f41729f1d6501"),
"name" : "string",
"explicitMods" : [
"12 to 18 to Blah"
]
}
/* 2 */
{
"_id" : ObjectId("5993a35be38f41729f1d6502"),
"name" : "string",
"explicitMods" : [
"12 to 18 to Blah"
]
}
あなたは、そのテーマの「ばらつき」を適用し、どの文書を決定するためにフィルタ条件に対する配列の「長さをテストする」ことができます返すために:それは$where
使用して「ネイティブ事業者」と、元のオプションと同じことをしながら
db.myCollection.aggregate([
{ "$match": { "explicitMods": /\d+ to \d+/ } },
{ "$addFields": { "origSize": { "$size": "$explicitMods" } } },
{ "$unwind": "$explicitMods" },
{ "$match": { "explicitMods": /\d+ to \d+/ } },
{ "$group": {
"_id": "$_id",
"name": { "$first": "$name" },
"origSize": { "$first": "$origSize" },
"explicitMods": { "$push": "$explicitMods" },
}},
{ "$redact": {
"$cond": {
"if": {
"$eq": [
{ "$size": "$explicitMods" },
"$origSize"
]
},
"then": "$$KEEP",
"else": "$$PRUNE"
}
}}
])
しかしを、$unwind
などの操作の一般的なコストは、それがユーティリティ疑問だので、かなり時間がかかりそうなります元のクエリよりも結果を生成するためのリソースが必要です。
質問を更新して、クエリが返すサンプルドキュメントを提供できますが、含まれたくないドキュメントはありますか? – JohnnyHK
あなたのお問い合わせがうまくいくようです。だからあなたはその文書の 'explicitMods'をフィルタリングしようとしていますか? – Mikey
"12〜18"の前後に他の文字を入れたくない場合は、正規表現の先頭に '^'を、または式の最後に '$'を置く必要があるかもしれません。 '/^\ d +〜\ d + $ /'のような式。それは助けるかもしれない? –