MongoDB에서 객체 배열(object array) 안에 있는 항목들을 가져오려면 aggregate() 메서드를 활용하면 됩니다. 이 글에서는 실제 예제를 통해 단계별로 살펴보겠습니다.
1. 샘플 컬렉션 생성하기
먼저 문서(document)를 포함하는 컬렉션을 생성합니다. 아래 예제에서는 demo459라는 컬렉션에 여러 객체가 중첩된 배열을 가진 문서를 하나 삽입합니다.
> db.demo459.insertOne(
... { "_id" : 1,
... "Information" : [
... {
... "Name" : "Chris",
... "_id" : new ObjectId(),
... "details" : [
... "HR"
... ]
... },
... {
...
... "Name" : "David",
... "_id" : new ObjectId(),
... "details" : [
... "Developer"
... ]
... },
... {
...
... "Name" : "Bob",
... "_id" : new ObjectId(),
... "details" : [
... "Account"
... ]
... }
... ]
... }
... )
{ "acknowledged" : true, "insertedId" : 1 }2. 저장된 문서 확인하기
컬렉션에 삽입된 모든 문서를 확인하려면 find() 메서드를 사용합니다.
> db.demo459.find();
위 쿼리를 실행하면 다음과 같은 결과가 출력됩니다.
{ "_id" : 1, "Information" : [ { "Name" : "Chris", "_id" : ObjectId("5e7ef4a7dbcb9adb296c95c9"),
"details" : [ "HR" ] }, { "Name" : "David", "_id" : ObjectId("5e7ef4a7dbcb9adb296c95ca"),
"details" : [ "Developer" ] }, { "Name" : "Bob", "_id" : ObjectId("5e7ef4a7dbcb9adb296c95cb"),
"details" : [ "Account" ] } ] }3. aggregate()로 객체 배열의 항목 가져오기
이제 객체 배열에서 원하는 항목만 추출하는 핵심 쿼리를 살펴보겠습니다. 이 쿼리는 네 개의 파이프라인 단계로 구성됩니다.
- $unwind:
Information배열을 개별 문서로 분해합니다. - $unwind: 내부에 중첩된
Information.details배열도 마찬가지로 분해합니다. - $match: 이름이
Chris또는Bob인 항목만 필터링합니다. - $group: 조건에 맞는 details 값을
$addToSet으로 수집하여 중복 없는 목록을 만듭니다.
> db.demo459.aggregate([
... { $unwind: '$Information' },
... { $unwind: '$Information.details' },
... { $match: { 'Information.Name': { $in: ["Chris","Bob"]} } },
... { $group: { _id: null, detailList: { $addToSet: '$Information.details' } } },
... ])위 집계 쿼리를 실행하면 다음과 같은 결과를 얻을 수 있습니다.
{ "_id" : null, "detailList" : [ "Account", "HR" ] }결과 해석
출력 결과를 보면 Chris와 Bob에 해당하는 details 값인 HR과 Account만 배열 형태로 반환된 것을 확인할 수 있습니다. $addToSet 연산자 덕분에 값이 자동으로 정렬되고 중복이 제거되어 깔끔한 목록이 만들어집니다.
이처럼 MongoDB에서는 $unwind, $match, $group 등의 집계 파이프라인 단계를 조합하면 중첩된 객체 배열 속 데이터를 유연하게 조회하고 가공할 수 있습니다.