MongoDB의 집계 프레임워크(aggregate())에서 $match 단계는 일반 find() 쿼리처럼 조건에 맞는 문서만 골라내는 파이프라인 단계입니다. 여기에 $or 연산자를 조합하면 여러 조건 중 하나라도 만족하는 문서를 손쉽게 필터링할 수 있습니다. 이 글에서는 실제 예제를 통해 $match와 $or를 함께 사용하는 방법을 단계별로 살펴보겠습니다.
1. 샘플 데이터로 컬렉션 생성하기
먼저 insertOne() 메서드를 사용해 학생 정보 문서들이 담긴 컬렉션을 생성합니다. 각 문서에는 이름(StudentFirstName), 성(StudentLastName), 나이(StudentAge) 필드가 포함되어 있습니다.
> db.aggregationFrameworkWithOrMatchDemo.insertOne({"StudentFirstName":"John", "StudentLastName":"Smith","StudentAge":23});{ "acknowledged" : true, "insertedId" : ObjectId("5c8ac3a96cea1f28b7aa080d")}> db.aggregationFrameworkWithOrMatchDemo.insertOne({"StudentFirstName":"Carol", "StudentLastName":"Tayor","StudentAge":24});{ "acknowledged" : true, "insertedId" : ObjectId("5c8ac3bc6cea1f28b7aa080e")}> db.aggregationFrameworkWithOrMatchDemo.insertOne({"StudentFirstName":"David", "StudentLastName":"Miller","StudentAge":21});{ "acknowledged" : true, "insertedId" : ObjectId("5c8ac3ce6cea1f28b7aa080f")}> db.aggregationFrameworkWithOrMatchDemo.insertOne({"StudentFirstName":"Bob", "StudentLastName":"Taylor","StudentAge":20});{ "acknowledged" : true, "insertedId" : ObjectId("5c8ac3e16cea1f28b7aa0810")}> db.aggregationFrameworkWithOrMatchDemo.insertOne({"StudentFirstName":"Robert", "StudentLastName":"Smith","StudentAge":20});{ "acknowledged" : true, "insertedId" : ObjectId("5c8ac3fb6cea1f28b7aa0811")}> db.aggregationFrameworkWithOrMatchDemo.insertOne({"StudentFirstName":"Mike", "StudentLastName":"Miller","StudentAge":27});{ "acknowledged" : true, "insertedId" : ObjectId("5c8ac4166cea1f28b7aa0812")}2. 저장된 전체 문서 확인하기
find() 메서드에 pretty()를 붙여 호출하면 컬렉션에 저장된 모든 문서를 보기 좋게 출력할 수 있습니다.
> db.aggregationFrameworkWithOrMatchDemo.find().pretty();
실행 결과는 다음과 같습니다. 총 6개의 문서가 저장되어 있는 것을 확인할 수 있습니다.
{ "_id" : ObjectId("5c8ac3a96cea1f28b7aa080d"), "StudentFirstName" : "John", "StudentLastName" : "Smith", "StudentAge" : 23}{ "_id" : ObjectId("5c8ac3bc6cea1f28b7aa080e"), "StudentFirstName" : "Carol", "StudentLastName" : "Tayor", "StudentAge" : 24}{ "_id" : ObjectId("5c8ac3ce6cea1f28b7aa080f"), "StudentFirstName" : "David", "StudentLastName" : "Miller", "StudentAge" : 21}{ "_id" : ObjectId("5c8ac3e16cea1f28b7aa0810"), "StudentFirstName" : "Bob", "StudentLastName" : "Taylor", "StudentAge" : 20}{ "_id" : ObjectId("5c8ac3fb6cea1f28b7aa0811"), "StudentFirstName" : "Robert", "StudentLastName" : "Smith", "StudentAge" : 20}{ "_id" : ObjectId("5c8ac4166cea1f28b7aa0812"), "StudentFirstName" : "Mike", "StudentLastName" : "Miller", "StudentAge" : 27}3. $match + $or로 조건부 집계 수행하기
이제 집계 프레임워크의 $match 단계 안에 $or 연산자를 적용해 보겠습니다. 아래 쿼리는 StudentLastName 값이 'Smith' 또는 'Miller'인 문서만 필터링합니다.
> db.aggregationFrameworkWithOrMatchDemo.aggregate({... $match: { $or: [{ StudentLastName: 'Smith' }, { StudentLastName: 'Miller' }] }}).pretty();쿼리를 실행하면 다음과 같이 성이 'Smith'이거나 'Miller'인 4개의 문서만 반환됩니다.
{ "_id" : ObjectId("5c8ac3a96cea1f28b7aa080d"), "StudentFirstName" : "John", "StudentLastName" : "Smith", "StudentAge" : 23}{ "_id" : ObjectId("5c8ac3ce6cea1f28b7aa080f"), "StudentFirstName" : "David", "StudentLastName" : "Miller", "StudentAge" : 21}{ "_id" : ObjectId("5c8ac3fb6cea1f28b7aa0811"), "StudentFirstName" : "Robert", "StudentLastName" : "Smith", "StudentAge" : 20}{ "_id" : ObjectId("5c8ac4166cea1f28b7aa0812"), "StudentFirstName" : "Mike", "StudentLastName" : "Miller", "StudentAge" : 27}결과를 보면 John Smith(23세), David Miller(21세), Robert Smith(20세), Mike Miller(27세) 네 명의 문서만 출력된 것을 확인할 수 있습니다. Carol Tayor와 Bob Taylor는 조건에 해당하지 않아 제외되었습니다.
참고: $in 연산자로 더 간결하게 작성하기
동일한 필드에 대해 OR 조건을 적용할 때는 $in 연산자를 사용하는 것이 더 간결하고 가독성이 좋습니다. 위 쿼리는 다음과 같이 바꿔 쓸 수 있습니다.
> db.aggregationFrameworkWithOrMatchDemo.aggregate({ $match: { StudentLastName: { $in: ['Smith', 'Miller'] } } }).pretty();두 방식 모두 동일한 결과를 반환하지만, 조건이 많아질수록 $in을 사용하는 편이 유지보수에 유리합니다. 반면 서로 다른 필드 간의 OR 조건이 필요하다면 $or 연산자를 그대로 활용하면 됩니다.