定義
$elemMatch$elemMatch演算子は、クエリ結果の<array>フィールドの内容を、$elemMatch条件に一致する最初の要素のみを含むように制限します。
使用上の考慮事項
返される要素
$演算子と$elemMatch演算子の両方が、条件に基づいて配列から最初に一致する要素を投影します。
$ 演算子は、クエリ ステートメントの条件に基づいて、コレクション内の各ドキュメントから最初に一致する配列要素を投影します。
$elemMatch プロジェクション演算子は明示的な条件引数を受け取ります。これにより、クエリにない条件に基づいて投影したり、配列の埋め込みドキュメント内の複数のフィールドに基づいて投影したりすることができます。例については、「配列フィールドの制限」を参照してください。
フィールドの順序
ドキュメント内のフィールドの順序に関係なく、既存フィールドの $elemMatch プロジェクションでは、他の既存フィールドを包含した後にフィールドが返されます。
たとえば、次のドキュメントを含む players コレクションを考えます。
db.players.insertOne( { name: "player1", games: [ { game: "abc", score: 8 }, { game: "xyz", score: 5 } ], joined: new Date("2020-01-01"), lastLogin: new Date("2020-05-01") } )
次のプロジェクションでは、ドキュメントではjoinedフィールドとlastLoginフィールドの前に フィールドがリストされているにもかかわらず、プロジェクションに含まれる他の既存フィールドの後にgamesフィールドが返されます。
db.players.find( {}, { games: { $elemMatch: { score: { $gt: 5 } } }, joined: 1, lastLogin: 1 } )
つまり、この操作は次のドキュメントを返します。
{ "_id" : ObjectId("5edef64a1c099fff6b033977"), "joined" : ISODate("2020-01-01T00:00:00Z"), "lastLogin" : ISODate("2020-05-01T00:00:00Z"), "games" : [ { "game" : "abc", "score" : 8 } ] }
制限事項
ビューにおける
db.collection.find()操作は$elemMatchプロジェクション演算子をサポートしていません。$elemMatchでは$textクエリ演算子を指定できません
例
$elemMatchプロジェクション演算子の例では、次のドキュメントを含むコレクションschoolsを前提としています。
{ _id: 1, zipcode: "63109", students: [ { name: "john", school: 102, age: 10 }, { name: "jess", school: 102, age: 11 }, { name: "jeff", school: 108, age: 15 } ] }, { _id: 2, zipcode: "63110", students: [ { name: "ajax", school: 100, age: 7 }, { name: "achilles", school: 100, age: 8 }, ], athletics: [ "swimming", "basketball", "football" ] }, { _id: 3, zipcode: "63109", students: [ { name: "ajax", school: 100, age: 7 }, { name: "achilles", school: 100, age: 8 }, ], athletics: [ "baseball", "basketball", "soccer" ] }, { _id: 4, zipcode: "63109", students: [ { name: "barney", school: 102, age: 7 }, { name: "ruth", school: 102, age: 16 }, ] }
郵便番号検索
この操作は、zipcode 値が "63109" である次のドキュメントを返し、$elemMatch を使用して students 配列を表示します。
{ "_id" : 1, "students" : [ { "name" : "john", "school" : 102, "age" : 10 } ] } { "_id" : 3 } { "_id" : 4, "students" : [ { "name" : "barney", "school" : 102, "age" : 7 } ] }
_idが1に等しいドキュメントの場合、students配列には、schoolフィールドが102に等しい複数の要素が含まれています。ただし、$elemMatchプロジェクションは配列から最初に一致する要素のみを返します。_idが3に等しいドキュメントでは、students配列のどの要素も$elemMatch条件に一致しなかったため、結果にstudentsフィールドは含まれません。
$elemMatch 複数のフィールド付き
$elemMatchプロジェクションでは、複数のフィールドに対して条件を指定できます。
この操作では、次のように、zipcode の値が "63109" である 3 つのドキュメントが返されます。
{ "_id" : 1, "students" : [ { "name" : "jess", "school" : 102, "age" : 11 } ] } { "_id" : 3 } { "_id" : 4, "students" : [ { "name" : "ruth", "school" : 102, "age" : 16 } ] }
が_id 3studentsに等しいドキュメントには、 条件に一致する配列要素がなかったため、$elemMatch フィールドは含まれていません。
$elemMatchへの引数は、 $elemMatchがプロジェクションしている配列の要素と一致します。 フィールド名で等価性を$elemMatchに指定すると、配列内のオブジェクトの一致が試行されます。 たとえば、 $elemMatchは、プロジェクションの次の配列内で、スカラー値ではなくオブジェクトを照合しようとします。
上記の例では、zipcode 値が "63109" であるドキュメントが返されますが、プロジェクション操作では一致する要素が見つからなかったため、これらのドキュメントには _idフィールドのみが含まれます。
この操作では、zipcode の値が "63109" である 3 つのドキュメントが返されます。返されるドキュメントには、_id フィールドと athletics 配列の一致する要素(存在する場合)が含まれます。
[ { _id: 1 }, { _id: 3, athletics: [ 'basketball' ] }, { _id: 4 } ]
_idが3に等しいドキュメントが、 $elemMatch条件に一致した唯一のドキュメントです。
Tip
$ (projection) 演算子