정의
$elemMatch
$elemMatch
연산자는 쿼리 결과에서<array>
필드의 내용이$elemMatch
조건과 일치하는 첫 번째 요소만 포함하도록 제한합니다.
사용 고려 사항
반환된 요소
$
연산자와 $elemMatch
연산자는 모두 조건에 따라 배열에서 일치하는 첫 번째 요소를 프로젝트합니다.
$
연산자는 query문의 일부 조건을 기반으로 컬렉션의 각 문서에서 첫 번째로 일치하는 배열 요소를 프로젝트합니다.
$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 }, ] }
다음 C# 클래스를 사용하여 이러한 문서를 모델링할 수 있습니다.
public class School { public string Id { get; set; } [ ] public string ZipCode { get; set; } public Student[] Students { get; set; } public string[] Athletics { get; set; } }
public class Student { public string Id { get; set; } public string Name { get; set; } public int School { get; set; } public int Age { get; set; } }
우편번호 검색
find()
작업은 zipcode
필드의 값이 "63109"
인 모든 문서를 쿼리합니다. $elemMatch
프로젝션은 school
필드의 값이 102
인 students
배열의 첫 번째 일치하는 요소만 반환합니다.
db.schools.find( { zipcode: "63109" }, { students: { $elemMatch: { school: 102 } } } )
.NET/ C# 운전자 사용할 때 $elemMatch
프로젝션 수행하려면 프로젝션 빌더에서 ElemMatch()
메서드를 호출합니다. 프로젝트 에 배열 필드 의 이름을 전달하고 배열 요소에 적용 할 필터하다 전달합니다.
다음 코드 예시 Zipcode
필드 의 값이 "63109"
인 모든 문서를 찾습니다. 일치하는 각 문서 에 대해 프로젝션 다음 필드를 반환합니다.
Id
중첩된
School
필드 의 값이102
인Students
배열 의 첫 번째 요소
var results = schoolsCollection .Find(s => s.ZipCode == "63109") .Project(Builders<School>.Projection.ElemMatch( field: school => school.Students, filter: student => student.School == 102 ) ).ToList();
이 작업은 zipcode
값이 인 다음 문서를 "63109"
반환하고 을 사용하여 students
배열 $elemMatch
프로젝션합니다.
{ "_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
필드가 포함되어 있지 않습니다. 이는 해당 문서의students
배열에$elemMatch
조건과 일치하는 요소가 없기 때문입니다.
$elemMatch
여러 필드와 함께 사용
프로젝션 여러 필드에 대한 기준을 지정할 수 $elemMatch
있습니다.
find()
작업은 zipcode
필드의 값이 "63109"
있는 모든 문서를 쿼리합니다. 프로젝션은 school
필드의 값이 102
이고 age
필드가 10
보다 큰 students
배열의 첫 번째 일치하는 요소가 포함됩니다.
db.schools.find( { zipcode: "63109" }, { students: { $elemMatch: { school: 102, age: { $gt: 10} } } } )
다음 코드 예시 Zipcode
필드 의 값이 "63109"
인 모든 문서를 찾습니다. 일치하는 각 문서 에 대해 프로젝션 다음 필드를 반환합니다.
Id
중첩된
School
필드 의 값이102
값이고Age
필드 값이10
보다 큰Students
배열 의 첫 번째 요소
var results = schoolsCollection .Find(s => s.ZipCode == "63109") .Project(Builders<School>.Projection.ElemMatch( field: school => school.Students, filter: student => (student.School == 102) && (student.Age > 10) ) ).ToList();
이 작업은 zipcode
값이 "63109"
인 세 개의 문서를 반환합니다.
{ "_id" : 1, "students" : [ { "name" : "jess", "school" : 102, "age" : 11 } ] } { "_id" : 3 } { "_id" : 4, "students" : [ { "name" : "ruth", "school" : 102, "age" : 16 } ] }
_id
가 3
인 문서는 $elemMatch
조건과 일치하는 배열 요소가 없으므로 students
필드가 포함되어 있지 않습니다.
$elemMatch
에 대한 인수는 $elemMatch
가 프로젝션하는 배열 의 요소와 일치합니다. 필드 이름과 함께 동등성을 $elemMatch
지정하면 배열 내의 객체를 일치시키려고 시도합니다. 예를 예시 $elemMatch
은 프로젝션 에서 다음에 대해 배열 내에서 스칼라 값 대신 객체를 일치시키려고 시도합니다.
db.schools.find( { zipcode: "63109" }, { athletics: { $elemMatch: { athletics: "basketball" } } })
var results = schoolsCollection .Find(s => s.ZipCode == "63109") .Project(Builders<School>.Projection.ElemMatch( "athletics", Builders<School>.Filter.Eq("athletics", "basketball")) ).ToList();
앞의 예에서는 zipcode
값이 "63109"
인 문서를 반환하지만 프로젝션 작업에서 일치하는 요소를 찾지 못했기 때문에 이러한 문서에는 _id
필드 만 포함됩니다.
스칼라 값을 일치시키려면 일치시키려는 스칼라 값({$eq: <scalar value>}
)과 함께 등호 연산자 를 사용합니다. 예를 예시, 다음 find()
작업은 zipcode
필드 값이 "63109"
인 모든 문서를 쿼리합니다. 프로젝션 에는 값이 basketball
인 athletics
배열 의 일치하는 요소가 포함됩니다.
db.schools.find( { zipcode: "63109" }, { athletics: { $elemMatch: { $eq: "basketball" } } })
.NET/ C# 운전자 사용할 때 배열 의 스칼라 값에 대해 $elemMatch
작업을 수행하려면 프로젝션 빌더에서 ElemMatch()
메서드를 호출합니다. 배열 필드 의 이름을 프로젝트 에 전달하고 필드 "$eq"
에 대한 동등성 필터하다 와 비교하려는 값을 전달합니다.
var results = schoolsCollection .Find(s => s.ZipCode == "63109") .Project(Builders<School>.Projection.ElemMatch( field: "athletics", filter: Builders<School>.Filter.Eq("$eq", "basketball")) ).ToList();
이 작업은 zipcode
값이 "63109"
인 세 개의 문서를 반환합니다. 반환된 문서에는 _id
필드 와 athletics
배열 의 일치하는 요소(있는 경우)가 포함됩니다.
[ { _id: 1 }, { _id: 3, athletics: [ 'basketball' ] }, { _id: 4 } ]
_id
가 3
인 문서 가 $elemMatch
기준과 일치하는 유일한 문서 입니다.
팁
$ (projection)
연산자