定義
$The positional
$operator limits the contents of an<array>to return the first element that matches the query condition on the array.Use
$in the projection document of thefind()method or thefindOne()method when you only need one particular array element in selected documents.指定された条件に一致する要素のみを含む配列を返すには、集計演算子「
$filter」を参照してください。
使用上の考慮事項
Both the $ operator and the $elemMatch operator project the first matching element from an array based on a condition.
The $ operator projects the first matching array element from each document in a collection based on some condition from the query statement.
The $elemMatch projection operator takes an explicit condition argument. This allows you to project based on a condition not in the query, or if you need to project based on multiple fields in the array's embedded documents. See Array Field Limitations for an example.
db.collection.find() operations on views do not support $ projection operator.
動作
構文
配列上の指定されたクエリ条件に一致する最初の配列要素を返すには、
db.collection.find( { <array>: <condition> ... }, { "<array>.$": 1 } ) db.collection.find( { <array.field>: <condition> ...}, { "<array>.$": 1 } )
You can use the $ operator to limit an <array> field, which does not appear in the query document. In previous versions of MongoDB, the <array> field being limited must appear in the query document.
db.collection.find( { <someOtherArray>: <condition> ... }, { "<array>.$" : 1 } )
重要
期待どおりの動作を実現するには、クエリドキュメントとプロジェクションドキュメントで使用される配列が同じ長さである必要があります。 配列の長さが異なる場合、特定のシナリオでは操作でエラーが発生する可能性があります。
配列フィールドの制限
MongoDB では、配列へのプロジェクションを処理するときに次のものが必要です。
Only one positional
$operator may appear in the projection document.クエリドキュメントには、配列フィールドを 1 つだけ表示する必要があります。クエリ ドキュメント内の追加の配列フィールドにより、未定義の動作が発生する可能性があります。
例えば、次のプロジェクションは未定義の動作につながる可能性があります。
db.collection.find( { <array>: <value>, <someOtherArray>: <value2> }, { "<array>.$": 1 } ) クエリドキュメントには、それが適用される配列フィールドに 1 つの条件のみを含める必要があります。複数の条件が内部的に互いに上書きされ、未定義の動作が発生する可能性があります。
配列内のドキュメントの複数のフィールドに条件を指定するには、
$elemMatchクエリ演算子を使用します。次のクエリは、grades配列内のmeanが 70 より大きくgradeが 90 より大きい最初のドキュメントを返します。db.students.find( { grades: { $elemMatch: { mean: { $gt: 70 }, grade: { $gt:90 } } } }, { "grades.$": 1 } ) ドキュメントの選択とそれらのドキュメント内のフィールドの選択に別々の条件が必要な場合は、
$elemMatch演算子を使用する必要があります。
sorts と位置演算子
When the find() method includes a sort(), the find() method applies the sort() to order the matching documents before it applies the positional $ projection operator.
If an array field contains multiple documents with the same field name and the find() method includes a sort() on that repeating field, the returned documents may not reflect the sort order because the sort was applied to the elements of the array before the $ projection operator.
位置演算子の配置制限
The $ projection operator can only appear at the end of the field path, for example "field.$" or "fieldA.fieldB.$".
たとえば、次の操作は無効です。
db.inventory.find( { }, { "instock.$.qty": 1 } )
To resolve, remove the component of the field path that follows the $ projection operator.
位置演算子と $slice の制限
find and findAndModify projection cannot include $slice projection expression as part of a $ projection expression.
たとえば、次の操作は無効です。
db.inventory.find( { "instock.qty": { $gt: 25 } }, { "instock.$": { $slice: 1 } } )
以前のバージョンでは、MongoDB はクエリ条件に一致する instock 配列の最初の要素(instock.$)を返します。つまり、位置プロジェクション"instock.$" が優先され、$slice:1 の処理はありません。"instock.$": { $slice: 1 } は他のドキュメント フィールドを除外しません。
例
プロジェクト配列の値
コレクション students には次のドキュメントが含まれています。
db.students.insertMany( [ { _id : 1, "semester" : 1, "grades" : [ 70, 87, 90 ] }, { _id : 2, "semester" : 1, "grades" : [ 90, 88, 92 ] }, { _id : 3, "semester" : 1, "grades" : [ 85, 100, 90 ] }, { _id : 4, "semester" : 2, "grades" : [ 79, 85, 80 ] }, { _id : 5, "semester" : 2, "grades" : [ 88, 88, 92 ] }, { _id : 6, "semester" : 2, "grades" : [ 95, 90, 96 ] } ] )
次のクエリでは、プロジェクション{ "grades.$": 1 }は、 gradesフィールドの85以上の最初の要素のみを返します。
db.students.find( { semester: 1, grades: { $gte: 85 } }, { "grades.$": 1 } )
この操作により、次のドキュメントが返されます。
{ "_id" : 1, "grades" : [ 87 ] } { "_id" : 2, "grades" : [ 90 ] } { "_id" : 3, "grades" : [ 85 ] }
Although the array field grades may contain multiple elements that are greater than or equal to 85, the $ projection operator returns only the first matching element from the array.
プロジェクト配列ドキュメント
students コレクションには、次のドキュメントが含まれ、grades フィールドはドキュメントの配列です。各ドキュメントには、次の 3 つのフィールド名 grade、 mean、 stdが含まれています。
db.students.insertMany( [ { _id : 7, semester: 3, "grades" : [ { grade: 80, mean: 75, std: 8 }, { grade: 85, mean: 90, std: 5 }, { grade: 90, mean: 85, std: 3 } ] }, { _id : 8, semester: 3, "grades" : [ { grade: 92, mean: 88, std: 8 }, { grade: 78, mean: 90, std: 5 }, { grade: 88, mean: 85, std: 3 } ] } ] )
次のクエリでは、プロジェクション { "grades.$": 1 } は grades フィールドの mean が 70 より大きい最初の要素のみを返します。
db.students.find( { "grades.mean": { $gt: 70 } }, { "grades.$": 1 } )
この操作により、次のドキュメントが返されます。
{ "_id" : 7, "grades" : [ { "grade" : 80, "mean" : 75, "std" : 8 } ] } { "_id" : 8, "grades" : [ { "grade" : 92, "mean" : 88, "std" : 8 } ] }