MongoDB를 사용하여 두 컬렉션을 하나의 컬렉션으로 결합

Mehvish Ashiq 2023년1월30일
  1. MongoDB를 사용하여 두 컬렉션을 하나의 컬렉션으로 결합
  2. $lookup 집계 단계를 사용하여 두 개의 컬렉션을 하나로 결합
  3. pipeline 연산자를 사용하여 지정된 조건에 따라 두 개의 컬렉션을 하나로 결합
  4. 결과 문서에 첨부하기 전에 $unwind 연산자를 사용하여 플랫 어레이에
  5. 집계 쿼리에서 $project 필터 단계를 사용하여 두 개의 컬렉션을 하나로 결합
  6. Compass(MongoDB의 그래픽 인터페이스)를 사용하여 두 컬렉션 결합
MongoDB를 사용하여 두 컬렉션을 하나의 컬렉션으로 결합

오늘은 $lookup 집계 단계, pipeline$unwind 연산자, $project 필터 단계, MongoDB Compass를 사용하여 두 컬렉션을 하나의 컬렉션으로 결합합니다.

MongoDB를 사용하여 두 컬렉션을 하나의 컬렉션으로 결합

MongoDB를 사용하여 두 컬렉션을 하나의 컬렉션으로 결합하는 다른 접근 방식이 있습니다. 그 중 일부가 아래에 나와 있으며 이 자습서에서 다룰 것입니다.

  1. $lookup 집계 단계를 사용하여 두 컬렉션을 결합합니다.
  2. pipeline 연산자를 사용하여 지정된 조건에 따라 두 컬렉션을 결합합니다.
  3. 결과 문서에 배열을 첨부하기 전에 $unwind 연산자를 사용하여 배열을 평면화합니다.
  4. 집계 쿼리에서 $project 필터 단계를 사용하여 두 컬렉션을 결합합니다.
  5. 나침반(MongoDB의 그래픽 인터페이스)을 사용하여 두 컬렉션 결합

위의 모든 시나리오에 대해 문서(MySQL의 레코드와 동일)로 채워진 두 개의 컬렉션(MySQL의 테이블과 동일)을 포함하는 데이터베이스가 있어야 합니다. 다음 쿼리를 사용하여 이를 수행했습니다. 당신도 그렇게 할 수 있습니다.

users 데이터베이스에 있는 usersInformationuserAddress라는 두 개의 컬렉션을 만듭니다. 또한 다음과 같이 문서로 채우십시오.

데이터베이스 및 컬렉션 생성:

> use users
> db.createCollection('userInformation')
> db.createCollection('userAddress')

userInformation 컬렉션을 두 개의 문서로 채웁니다.

> db.userInformation.insertMany(
    [
        {
            fullname: 'Mehvish Ashiq',
            age: 30,
            gender: 'Female',
            nationality: 'Pakistani'
        },
        {
            fullname: 'James Daniel',
            age: 45,
            sex: 'male',
            nationality: 'Canadian'
        }
    ]
)

userAddress 컬렉션을 두 개의 문서로 채웁니다.

> db.userAddress.insertMany(
    [
        {
            fullname: 'Mehvish Ashiq',
            block_number: 22,
            street: 'Johar Town Street',
            city: 'Lahore'
        },
        {
            fullname: 'James Daniel',
            block_number: 30,
            street: 'Saint-Denis Street',
            city: 'Montreal'
        }
    ]
)

insertMany() 함수를 사용하여 여러 문서를 삽입합니다. 이제 아래 명령을 사용하여 두 컬렉션의 데이터를 볼 수 있습니다.

다음 코드 조각에서 pretty() 메서드는 셸에서 이해하기 쉬운 깨끗하고 형식이 지정된 출력을 보여줍니다.

userInformation에서 문서 표시:

> db.userInformation.find().pretty()

출력:

{
        "_id" : ObjectId("628bc4a45c544feccff5a566"),
        "fullname" : "Mehvish Ashiq",
        "age" : 30,
        "gender" : "Female",
        "nationality" : "Pakistani"
}
{
        "_id" : ObjectId("628bc4a45c544feccff5a567"),
        "fullname" : "James Daniel",
        "age" : 45,
        "sex" : "male",
        "nationality" : "Canadian"
}

userAddress의 문서 표시:

> db.userAddress.find().pretty()

출력:

{
        "_id" : ObjectId("628bc4ae5c544feccff5a568"),
        "fullname" : "Mehvish Ashiq",
        "block_number" : 22,
        "street" : "Johar Town Street",
        "city" : "Lahore"
}
{
        "_id" : ObjectId("628bc4ae5c544feccff5a569"),
        "fullname" : "James Daniel",
        "block_number" : 30,
        "street" : "Saint-Denis Street",
        "city" : "Montreal"
}

$lookup 집계 단계를 사용하려면 두 컬렉션이 동일한 데이터베이스에 있어야 합니다. 두 컬렉션이 모두 준비되면 우리가 가지고 있는 시나리오에 따라 다양한 쿼리를 사용하여 두 컬렉션의 데이터를 결합할 수 있습니다.

$lookup 집계 단계를 사용하여 두 개의 컬렉션을 하나로 결합

예제 코드:

> db.userInformation.aggregate([
    { $lookup:
        {
           from: 'userAddress',
           localField: 'fullname',
           foreignField: 'fullname',
           as: 'address'
        }
    }
]).pretty();

출력:

{
        "_id" : ObjectId("628bc4a45c544feccff5a566"),
        "fullname" : "Mehvish Ashiq",
        "age" : 30,
        "gender" : "Female",
        "nationality" : "Pakistani",
        "address" : [
                {
                        "_id" : ObjectId("628bc4ae5c544feccff5a568"),
                        "fullname" : "Mehvish Ashiq",
                        "block_number" : 22,
                        "street" : "Johar Town Street",
                        "city" : "Lahore"
                }
        ]
}
{
        "_id" : ObjectId("628bc4a45c544feccff5a567"),
        "fullname" : "James Daniel",
        "age" : 45,
        "sex" : "male",
        "nationality" : "Canadian",
        "address" : [
                {
                        "_id" : ObjectId("628bc4ae5c544feccff5a569"),
                        "fullname" : "James Daniel",
                        "block_number" : 30,
                        "street" : "Saint-Denis Street",
                        "city" : "Montreal"
                }
        ]
}

MongoDB 데이터베이스에서 $lookup집계 단계는 다른 컬렉션과의 왼쪽 외부 조인을 수행하고 조인된 문서의 정보(데이터)도 필터링합니다. 예를 들어, 쿼리를 사용하여 주소와 함께 모든 사용자의 정보를 가져옵니다.

$lookup 기능은 4개의 필드를 허용합니다. 첫 번째는 from 필드로, 다른 컬렉션과 결합되어야 하는 컬렉션을 지정합니다.

두 번째는 localField 필드입니다. from 필드에 지정된 컬렉션의 입력 문서에 있는 속성(필드) 중 하나입니다.

컬렉션 문서의 localField에서 foreignField로의 일치를 수행하는 데 사용됩니다.

유사하게 foreignField라는 세 번째 필드도 컬렉션 문서의 foreignField에서 localField에 대한 동등 일치를 수행합니다.

네 번째 필드 as에 대한 새 어레이 이름을 씁니다. $lookup 집계 단계에 대한 다음 설명을 참조하십시오.

mongodb를 사용하여 두 개의 컬렉션을 하나의 컬렉션으로 결합 - 조회 단계 설명

pipeline 연산자를 사용하여 지정된 조건에 따라 두 개의 컬렉션을 하나로 결합

예제 코드:

> db.userInformation.aggregate([{
    $lookup:{
        from: 'userAddress',
        let: {full_name: '$fullname'},
        pipeline: [{
            $match: {
                $expr: {
                    $eq: ['$fullname', '$$full_name']
                }
             }
       }],
       as: 'addressInfo'
    }
}]).pretty()

출력:

{
        "_id" : ObjectId("628bc4a45c544feccff5a566"),
        "fullname" : "Mehvish Ashiq",
        "age" : 30,
        "gender" : "Female",
        "nationality" : "Pakistani",
        "addressInfo" : [
                {
                        "_id" : ObjectId("628bc4ae5c544feccff5a568"),
                        "fullname" : "Mehvish Ashiq",
                        "block_number" : 22,
                        "street" : "Johar Town Street",
                        "city" : "Lahore"
                }
        ]
}
{
        "_id" : ObjectId("628bc4a45c544feccff5a567"),
        "fullname" : "James Daniel",
        "age" : 45,
        "sex" : "male",
        "nationality" : "Canadian",
        "addressInfo" : [
                {
                        "_id" : ObjectId("628bc4ae5c544feccff5a569"),
                        "fullname" : "James Daniel",
                        "block_number" : 30,
                        "street" : "Saint-Denis Street",
                        "city" : "Montreal"
                }
        ]
}

(MySQL에서 WHERE 절을 사용하는 것처럼) 특정 조건에 따라 두 컬렉션을 결합하려는 경우 파이프라인 연산자를 $lookup과 함께 사용할 수 있습니다.

예를 들어, userAddressfullnameuserInformationfullname과 동일한 컬렉션에 합류합니다.

결과 문서에 첨부하기 전에 $unwind 연산자를 사용하여 플랫 어레이에

예제 코드:

> db.userInformation.aggregate([
    { $lookup:
        {
           from: 'userAddress',
           localField: 'fullname',
           foreignField: 'fullname',
           as: 'address'
        }
    },
    {
       $unwind: '$address'
    }
]).pretty();

출력:

{
        "_id" : ObjectId("628bc4a45c544feccff5a566"),
        "fullname" : "Mehvish Ashiq",
        "age" : 30,
        "gender" : "Female",
        "nationality" : "Pakistani",
        "address" : {
                "_id" : ObjectId("628bc4ae5c544feccff5a568"),
                "fullname" : "Mehvish Ashiq",
                "block_number" : 22,
                "street" : "Johar Town Street",
                "city" : "Lahore"
        }
}
{
        "_id" : ObjectId("628bc4a45c544feccff5a567"),
        "fullname" : "James Daniel",
        "age" : 45,
        "sex" : "male",
        "nationality" : "Canadian",
        "address" : {
                "_id" : ObjectId("628bc4ae5c544feccff5a569"),
                "fullname" : "James Daniel",
                "block_number" : 30,
                "street" : "Saint-Denis Street",
                "city" : "Montreal"
        }
}

$unwind 연산자는 결과 문서에 연결하기 전에 배열을 평평하게 만드는 것 외에는 아무 작업도 수행하지 않습니다. $unwind 연산자의 근본적인 차이점은 단일 요소가 있는 배열을 요소 자체인 평평한 개체로 변환한다는 것입니다.

이 요소의 이름은 변경되지 않습니다. 요소가 배열 형태였을 때와 같을 것입니다.

$unwind 연산자를 사용하거나 사용하지 않고 위 쿼리를 실행하고 address 필드를 관찰합니다.

집계 쿼리에서 $project 필터 단계를 사용하여 두 개의 컬렉션을 하나로 결합

$project를 사용하여 컬렉션에 합류하기 전에 그 중요성을 이해합시다. 예를 들어 userAddress라는 이름의 전체 컬렉션을 userInformation과 결합하지 않으려면 citystreet 필드만 결합되기를 원합니다.

이 경우 $addFields 단계를 사용해야 합니다. 이 단계를 사용하여 배열/객체의 필드 또는 여러 필드를 문서의 루트 수준에 결합/할당합니다.

그래서 우리는 userAddress 컬렉션에서 citystreet를 검색하기 위해 다음 쿼리를 실행합니다.

예제 코드:

> db.userInformation.aggregate([
    { $lookup:
        {
           from: 'userAddress',
           localField: 'fullname',
           foreignField: 'fullname',
           as: 'address'
        }
    },
    {
       $unwind: '$address'
    },
    {
       $addFields: {
           street: '$address.street',
           city: '$address.city'
       }
    }
]).pretty();

출력:

{
        "_id" : ObjectId("628bc4a45c544feccff5a566"),
        "fullname" : "Mehvish Ashiq",
        "age" : 30,
        "gender" : "Female",
        "nationality" : "Pakistani",
        "address" : {
                "_id" : ObjectId("628bc4ae5c544feccff5a568"),
                "fullname" : "Mehvish Ashiq",
                "block_number" : 22,
                "street" : "Johar Town Street",
                "city" : "Lahore"
        },
        "street" : "Johar Town Street",
        "city" : "Lahore"
}
{
        "_id" : ObjectId("628bc4a45c544feccff5a567"),
        "fullname" : "James Daniel",
        "age" : 45,
        "sex" : "male",
        "nationality" : "Canadian",
        "address" : {
                "_id" : ObjectId("628bc4ae5c544feccff5a569"),
                "fullname" : "James Daniel",
                "block_number" : 30,
                "street" : "Saint-Denis Street",
                "city" : "Montreal"
        },
        "street" : "Saint-Denis Street",
        "city" : "Montreal"
}

위에 주어진 출력에 주의하여 집중하십시오. streetcity가 표시되나요? 예, 문서의 루트 수준에서 streetcity를 가져오고 있지만 현재 필요하지 않은 address 개체도 있습니다.

여기에서 $project 필터 단계가 등장합니다. 결과 문서에 어떤 필드가 있어야 하는지 지정합니다.

더 나은 이해를 위해 다음 쿼리를 참조하십시오.

예제 코드:

> db.userInformation.aggregate([
    { $lookup:
        {
           from: 'userAddress',
           localField: 'fullname',
           foreignField: 'fullname',
           as: 'address'
        }
    },
    {
       $unwind: '$address'
    },
    {
       $addFields: {
           street: '$address.street',
           city: '$address.city'
       }
    },
    {
       $project: {
           fullname: 1,
           age: 1,
           gender: 1,
           street: 1,
           city: 1
       }
    }
]).pretty();

출력:

{
        "_id" : ObjectId("628bc4a45c544feccff5a566"),
        "fullname" : "Mehvish Ashiq",
        "age" : 30,
        "gender" : "Female",
        "street" : "Johar Town Street",
        "city" : "Lahore"
}
{
        "_id" : ObjectId("628bc4a45c544feccff5a567"),
        "fullname" : "James Daniel",
        "age" : 45,
        "street" : "Saint-Denis Street",
        "city" : "Montreal"
}

보시다시피 address 개체는 없지만 두 필드(streetcity)는 문서의 루트 수준에 할당됩니다.

Compass(MongoDB의 그래픽 인터페이스)를 사용하여 두 컬렉션 결합

그래픽 인터페이스를 사용한 집계는 쉽습니다. $lookup 집계 단계에서는 다음 단계만 수행하면 됩니다.

  1. MongoDBCompass를 열고 서버에 연결합니다.

  2. 원하는 경우 완전히 새로운 데이터베이스와 두 개의 컬렉션을 만듭니다. 우리는 Mongo 셸을 사용하여 생성한 것과 동일한 데이터베이스와 컬렉션을 사용합니다.

  3. 다음과 같은 컬렉션을 엽니다.

    mongodb를 사용하여 두 개의 컬렉션을 하나의 컬렉션으로 결합 - compass open collections

  4. 프로젝트 요구 사항에 따라 단계를 추가합니다. $lookup 집계 단계를 추가합니다. $lookup 필드를 업데이트하고 오른쪽에서 원하는 결과를 확인하십시오.

    mongodb를 사용하여 두 컬렉션을 하나의 컬렉션으로 결합 - 나침반 추가 조회 단계

Mehvish Ashiq avatar Mehvish Ashiq avatar

Mehvish Ashiq is a former Java Programmer and a Data Science enthusiast who leverages her expertise to help others to learn and grow by creating interesting, useful, and reader-friendly content in Computer Programming, Data Science, and Technology.

LinkedIn GitHub Facebook

관련 문장 - MongoDB Collection

관련 문장 - MongoDB Join