Computer >> 컴퓨터 >  >> 프로그래밍 >> MongoDB

MongoDB에서 ObjectId 배열에 대해 $lookup 수행하는 방법

MongoDB에서 한 컬렉션에 저장된 ObjectId 배열을 기준으로 다른 컬렉션의 문서를 가져오려면 $lookup을 사용하면 됩니다. $lookup은 동일한 데이터베이스 내의 샤딩되지 않은(unsharded) 컬렉션에 대해 왼쪽 외부 조인(left outer join)을 수행하며, 조인된 컬렉션의 문서를 필터링하여 처리할 수 있습니다.

특히 배열 형태로 저장된 ObjectId 목록을 조인 키로 활용하려면 일반적인 localField/foreignField 방식 대신 let, pipeline, 그리고 $expr과 함께 $in 연산자를 조합해야 합니다. 아래 예제를 통해 단계별로 살펴보겠습니다.

1. 첫 번째 컬렉션 생성

먼저 문서가 포함된 컬렉션을 생성합니다.

> db.demo395.insertOne({Name:"Chris"});
{
   "acknowledged" : true,
   "insertedId" : ObjectId("5e5e782317aa3ef9ab8ab207")
}
> db.demo395.insertOne({Name:"David"});
{
   "acknowledged" : true,
   "insertedId" : ObjectId("5e5e782317aa3ef9ab8ab208")
}

find() 메서드를 사용하여 컬렉션의 모든 문서를 확인합니다.

> db.demo395.find();

실행 결과는 다음과 같습니다.

{ "_id" : ObjectId("5e5e782317aa3ef9ab8ab207"), "Name" : "Chris" }
{ "_id" : ObjectId("5e5e782317aa3ef9ab8ab208"), "Name" : "David" }

2. ObjectId 배열을 포함하는 두 번째 컬렉션 생성

이번에는 앞서 생성한 문서들의 ObjectId를 배열로 가지는 두 번째 컬렉션을 만들어 보겠습니다.

> db.demo396.insertOne({"details" : [{
   "acknowledged" : true,
   "insertedId" : ObjectId("5e5e787817aa3ef9ab8ab209")
}

마찬가지로 find() 메서드로 문서를 조회합니다.

> db.demo396.find();

실행 결과는 다음과 같습니다.

{ "_id" : ObjectId("5e5e787817aa3ef9ab8ab209"), "details" : [

3. ObjectId 배열에 대해 $lookup 수행하기

다음은 details 필드의 ObjectId 배열을 기준으로 demo395 컬렉션과 조인하는 $lookup 쿼리입니다. 핵심은 let으로 현재 문서의 배열 값을 변수에 담고, 파이프라인 내부의 $match에서 $expr$in을 사용해 해당 배열에 포함된 _id만 필터링하는 것입니다.

> db.demo396.aggregate([

실행 결과는 다음과 같습니다. details 배열에 담긴 ObjectId와 일치하는 문서들이 output 필드에 배열 형태로 반환됩니다.

{ "_id" : ObjectId("5e5e787817aa3ef9ab8ab209"), "details" : [ ObjectId("5e5e782317aa3ef9ab8ab207"), ObjectId("5e5e782317aa3ef9ab8ab208") ], "output" : [ { "_id" : ObjectId("5e5e782317aa3ef9ab8ab207"), "Name" : "Chris" }, { "_id" : ObjectId("5e5e782317aa3ef9ab8ab208"), "Name" : "David" } ] }

정리

이처럼 MongoDB에서 ObjectId 배열을 조인 키로 사용할 때는 $lookup의 let 옵션으로 배열을 변수화하고, pipeline 안에서 $match + $expr + $in 조합으로 매칭하면 됩니다. 이 방식은 배열의 크기나 순서에 관계없이 유연하게 동작하므로, 참조 문서 목록을 배열로 관리하는 스키마 설계에서 특히 유용합니다.