AI エージェント向け: ドキュメントインデックスは https://www.mongodb.com/ja-jp/docs/llms.txt で利用できます。すべてのページの markdown バージョンは、いずれかの URL パスに .md を追加することで利用できます。

$filter(式 演算子)

$filter

指定条件に基づいて、配列のサブセットを選択して返します。条件に一致する要素のみを含む配列を返します。返される要素は元の順序のままです。

次の環境でホストされる配置には $filter を使用できます。

  • MongoDB Atlas はクラウドでの MongoDB 配置のためのフルマネージド サービスです
  • MongoDB Enterprise: サブスクリプションベースの自己管理型 MongoDB バージョン

  • MongoDB Community: ソースが利用可能で、無料で使用できる自己管理型の MongoDB のバージョン

$filter の構文は次のとおりです。

{ $filter: { input: <array expression>, as: <string>, arrayIndexAs: <string>, cond: <expression>, limit: <number expression> }}
フィールド
仕様

input

配列に解決される式。

input が null に解決されるか、欠落しているフィールドを参照する場合、$filter は null を返します。

input が配列以外、null 以外の値に解決される場合、パイプラインはエラーになります。

as

任意。input 配列の各要素を表す変数の名前。名前が指定されていない場合、変数名はデフォルトで this になります。

arrayIndexAs

任意.input 配列内の現在の要素のインデックスを表す集計変数の名前。最初の配列要素インデックスは 0 です。

変数名は式で使用できます。例、arrayIndexAs: "myIndex" を指定した場合、式では $$myIndex が使用されます。$$myIndex は、input 配列内の現在の要素のインデックスを返します。

arrayIndexAs を省略する場合は、式で $$IDX システム変数を使用して現在の要素のインデックスを返すことができます。

例については、「配列内の各項目のインデックスへのアクセス」および「$$IDXを使用したインデックスへのアクセス」を参照してください。

バージョン8.3の新機能。

cond

式 は、ブール値に解決され、要素が出力配列に含まれるべきかどうかを判断するために使用されます。この式は、input 配列の各要素を、as で指定された変数名で個別に参照します。

limit

任意。 $filterが返す一致する配列要素の数を制限する数値式。 1未満の制限は指定できません。 一致する配列要素は、入力配列に現れる順序で返されます。

指定されたlimitが一致する配列要素の数より大きい場合、 $filterは一致するすべての配列要素を返します。 制限がnullの場合、 $filterは一致するすべての配列要素を返します。

式の詳細については、「式 」を参照してください。

例
結果
{ $filter: { input: [ 1, "a", 2, null, 3.1, Long(4), "5" ], as: "num", cond: { $isNumber: "$$num" } }}

[ 1, 2, 3.1, Long(4) ]

{ $filter: { input: [ 1, "a", 2, null, 3.1, Long(4), "5" ], as: "num", cond: { $isNumber: "$$num" }, limit: 2 }}

[ 1, 2 ]

{ $filter: { input: [ 1, "a", 2, null, 3.1, Long(4), "5" ], as: "num", cond: { $isNumber: "$$num" }, limit: { $add: [ 0, 1 ] } }}

[ 1 ]

次の例では、次のドキュメントを含むsalesコレクションを使用します。

db.sales.insertMany( [ { _id: 0, items: [ { item_id: 43, quantity: 2, price: 10, name: "pen" }, { item_id: 2, quantity: 1, price: 240, name: "briefcase" } ] }, { _id: 1, items: [ { item_id: 23, quantity: 3, price: 110, name: "notebook" }, { item_id: 103, quantity: 4, price: 5, name: "pen" }, { item_id: 38, quantity: 1, price: 300, name: "printer" } ] }, { _id: 2, items: [ { item_id: 4, quantity: 1, price: 23, name: "paper" } ] }] )

次の例では、items 配列をフィルタリングして、price が 100 以上のドキュメントのみを含めます。

db.sales.aggregate( [ { $project: { items: { $filter: { input: "$items", as: "item", cond: { $gte: [ "$$item.price", 100 ] } } } } }] )
[ { _id: 0, items: [ { item_id: 2, quantity: 1, price: 240, name: 'briefcase' } ] }, { _id: 1, items: [ { item_id: 23, quantity: 3, price: 110, name: 'notebook' }, { item_id: 38, quantity: 1, price: 300, name: 'printer' } ] }, { _id: 2, items: [] }]

この例では、 limitフィールドを使用して、各items配列で返される一致する要素の数を指定します。

db.sales.aggregate( [ { $project: { items: { $filter: { input: "$items", as: "item", cond: { $gte: [ "$$item.price", 100 ] }, limit: 1 } } } }] )
[ { _id: 0, items: [ { item_id: 2, quantity: 1, price: 240, name: 'briefcase' } ] }, { _id: 1, items: [ { item_id: 23, quantity: 3, price: 110, name: 'notebook' } ] }, { _id: 2, items: [] }]

この例では、返される一致する要素の可能な数より大きいlimitフィールド値が使用されています。 この場合、 limitはクエリ結果に影響を与えず、 $gteフィルタ条件に一致するすべてのドキュメントを返します。

db.sales.aggregate( [ { $project: { items: { $filter: { input: "$items", as: "item", cond: { $gte: [ "$$item.price", 100] }, limit: 5 } } } }] )
[ { _id: 0, items: [ { item_id: 2, quantity: 1, price: 240, name: 'briefcase' } ] }, { _id: 1, items: [ { item_id: 23, quantity: 3, price: 110, name: 'notebook' }, { item_id: 38, quantity: 1, price: 300, name: 'printer' } ] }, { _id: 2, items: [] }]

以下のitemsの集計フィルターでは、 nameの値はpenです。

db.sales.aggregate( [ { $project: { items: { $filter: { input: "$items", as: "item", cond: { $eq: [ "$$item.name", "pen"] } } } } }] )
[ { _id: 0, items: [ { item_id: 43, quantity: 2, price: 10, name: 'pen' } ] }, { _id: 1, items: [ { item_id: 103, quantity: 4, price: 5, name: 'pen' } ] }, { _id: 2, items: [] }]

次の集計では、 $regexMatchを使用して、 pで始まるname値を持つitemsをフィルタリングします。

db.sales.aggregate( [ { $project: { items: { $filter: { input: "$items", as: "item", cond: { $regexMatch: { input: "$$item.name", regex: /^p/ } } } } } }] )
[ { _id: 0, items: [ { item_id: 43, quantity: 2, price: 10, name: 'pen' } ] }, { _id: 1, items: [ { item_id: 103, quantity: 4, price: 5, name: 'pen' }, { item_id: 38, quantity: 1, price: 300, name: 'printer' } ] }, { _id: 2, items: [ { item_id: 4, quantity: 1, price: 23, name: 'paper' } ] }]

これらのdocumentを使用して、people という名前のサンプルコレクションを作成します。

db.people.insertMany( [ { _id: 1, name: "Melissa", hobbies: [ "softball", "drawing", "reading" ] }, { _id: 2, name: "Brad", hobbies: [ "gaming", "skateboarding" ] }, { _id: 3, name: "Scott", hobbies: [ "basketball", "music", "fishing" ] }, { _id: 4, name: "Tracey", hobbies: [ "acting", "yoga" ] }, { _id: 5, name: "Josh", hobbies: [ "programming" ] }, { _id: 6, name: "Claire" }] )

hobbiesフィールドには、各人の趣味の配列がランク付けされています。配列の最初の趣味は、人が最も多くの時間を費やしたその人のプライマリ趣味です。最初の趣味の配列インデックスは 0 です。

次の例ではarrayIndexAs を使用しています。myIndex 変数には、hobbies 配列内の各趣味のインデックスがあります。この例では、次のフィールドを持つdocumentが返されます。

  • 人の名前。

  • secondaryHobbies その他のすべての趣味を含む配列

db.people.aggregate( [ { $project: { _id: 0, name: 1, secondaryHobbies: { $filter: { input: "$hobbies", arrayIndexAs: "myIndex", cond: { $eq: [ { $mod: [ "$$myIndex", 2 ] }, 0 ] } } } } }] )

出力:

[ { "name" : "Melissa", "secondaryHobbies" : [ "softball", "reading" ] } { "name" : "Brad", "secondaryHobbies" : [ "gaming" ] } { "name" : "Scott", "secondaryHobbies" : [ "basketball", "fishing" ] } { "name" : "Tracey", "secondaryHobbies" : [ "acting" ] } { "name" : "Josh", "secondaryHobbies" : [ "programming" ] } { "name" : "Claire", "secondaryHobbies" : null }]

$$IDX 変数は、input 配列内の現在の要素のインデックスを返します。式から arrayIndexAsフィールドを省略すると、$$IDX を使用できます。

次の例では、前のセクションの例と同じdocumentが返されます。配列内の各項目のインデックスにアクセスする、ただし、arrayIndexAs ではなく $$IDX が使用されています。

db.people.aggregate( [ { $project: { _id: 0, name: 1, secondaryHobbies: { $filter: { input: "$hobbies", cond: { $eq: [ { $mod: [ "$$IDX", 2 ] }, 0 ] } } } } }] )