MongoDB에서는 하나의 문서 안에 또 다른 문서나 배열이 포함된 중첩(nested) 구조를 자주 사용합니다. 이런 구조에서 특정 데이터를 조회하려면 점 표기법(dot notation)을 활용한 중첩 쿼리를 작성해야 합니다. 이번 글에서는 MongoDB 4 환경에서 중첩된 필드 경로를 조건으로 지정해 원하는 문서만 정확히 가져오는 방법을 단계별로 살펴보겠습니다.
1. 샘플 컬렉션 생성하기
먼저 중첩 쿼리 실습을 위해 문서가 포함된 컬렉션을 생성합니다. 아래 예제에서는 ProductDetails 객체 안에 StockDetails 배열이 들어 있는 2단계 중첩 구조의 문서 두 개를 삽입했습니다.
> db.demo492.insertOne({
... "ProductDetails" :
... {
... "StockDetails" : [
... { "ProductName" : "Product-1" },
... { "ProductName" : "Product-2" },
... { "ProductName" : "Product-3" }
... ]
... }
... });
{
"acknowledged" : true,
"insertedId" : ObjectId("5e849db8b0f3fa88e22790c2")
}
>
> db.demo492.insertOne({
... "ProductDetails" :
... {
... "StockDetails" : [
... { "ProductName" : "Product-4" },
... { "ProductName" : "Product-5" },
... { "ProductName" : "Product-6" }
... ]
... }
... });
{
"acknowledged" : true,
"insertedId" : ObjectId("5e849dceb0f3fa88e22790c3")
}2. 전체 문서 확인하기
find() 메서드를 사용하면 컬렉션에 저장된 모든 문서를 한눈에 확인할 수 있습니다.
> db.demo492.find();
위 명령을 실행하면 다음과 같은 결과가 출력됩니다.
{ "_id" : ObjectId("5e849db8b0f3fa88e22790c2"), "ProductDetails" : { "StockDetails" : [ {
"ProductName" : "Product-1" }, { "ProductName" : "Product-2" }, { "ProductName" : "Product-3" } ] } }
{ "_id" : ObjectId("5e849dceb0f3fa88e22790c3"), "ProductDetails" : { "StockDetails" : [ {
"ProductName" : "Product-4" }, { "ProductName" : "Product-5" }, { "ProductName" : "Product-6" } ] } }3. 점 표기법으로 특정 문서 조회하기
이제 핵심인 중첩 쿼리입니다. MongoDB에서는 상위필드.하위필드 형태의 점 표기법을 사용해 중첩된 필드에 직접 접근할 수 있습니다. 아래 예제는 ProductDetails.StockDetails.ProductName 값이 "Product-1"인 문서만 조회하는 쿼리입니다.
> db.demo492.find({ "ProductDetails.StockDetails.ProductName":"Product-1"});실행 결과, 조건에 일치하는 첫 번째 문서만 반환되는 것을 확인할 수 있습니다.
{ "_id" : ObjectId("5e849db8b0f3fa88e22790c2"), "ProductDetails" : { "StockDetails" : [ {
"ProductName" : "Product-1" }, { "ProductName" : "Product-2" }, { "ProductName" : "Product-3" } ] } }마무리
이처럼 MongoDB에서는 점 표기법만 활용하면 몇 단계로 중첩된 문서라도 손쉽게 조회할 수 있습니다. 참고로 배열 내부의 특정 위치 요소를 조회하고 싶다면 StockDetails.0.ProductName처럼 인덱스를 함께 지정할 수도 있으며, 복잡한 조건이 필요하다면 $elemMatch 연산자를 사용하는 것이 좋습니다. 중첩 쿼리에 익숙해지면 대량의 계층형 데이터도 효율적으로 다룰 수 있습니다.