MongoDB 문서 연결

MongoDBBeginner
지금 연습하기

소개

이 랩에서는 MongoDB 에서 문서 간 관계를 설정하는 기본 사항을 배우게 됩니다. 참조 (referencing) 라고 알려진 이 기술은 복잡하고 체계적인 데이터베이스 구조를 구축하는 데 필수적입니다. 컬렉션을 생성하고, 다른 문서에 대한 참조가 포함된 문서를 삽입하고, $lookup 집계 단계를 사용하여 관련 데이터를 검색 및 결합하고, 이러한 연결된 문서의 수명 주기를 관리하는 연습을 하게 됩니다. 이 랩이 끝나면 MongoDB 데이터베이스에서 일대다 (one-to-many) 관계를 모델링하고 관리하는 방법에 대한 확실한 이해를 갖게 될 것입니다.

이것은 가이드 실험입니다. 학습과 실습을 돕기 위한 단계별 지침을 제공합니다.각 단계를 완료하고 실무 경험을 쌓기 위해 지침을 주의 깊게 따르세요. 과거 데이터에 따르면, 이것은 초급 레벨의 실험이며 완료율은 100%입니다.학습자들로부터 100%의 긍정적인 리뷰율을 받았습니다.

문서 관계 설정

첫 번째 단계에서는 두 개의 별도 컬렉션을 생성하고 그들 간의 관계를 설정합니다. 라이브러리 데이터베이스에 authorsbooks가 있는 일반적인 시나리오를 모델링할 것입니다. 각 책은 해당 저자를 참조하게 됩니다.

먼저 MongoDB Shell 을 엽니다. 이 대화형 명령줄 인터페이스를 통해 MongoDB 인스턴스와 상호 작용할 수 있습니다.

mongosh

쉘에 들어가면 test> 프롬프트가 표시됩니다. library_database라는 새 데이터베이스로 전환해 보겠습니다. 데이터베이스가 존재하지 않으면 MongoDB 는 데이터를 처음 저장할 때 자동으로 생성합니다.

use library_database

이제 두 개의 문서를 삽입하여 authors 컬렉션을 생성해 보겠습니다. 각 문서에는 ObjectId 유형의 고유한 _id가 있으며, 이를 참조에 사용할 것입니다.

db.authors.insertMany([
  {
    _id: ObjectId("660a1f5c9b8f8b1234567890"),
    name: "Jane Austen",
    nationality: "British"
  },
  {
    _id: ObjectId("660a1f5c9b8f8b1234567891"),
    name: "George Orwell",
    nationality: "British"
  }
]);

문서가 성공적으로 삽입되었다는 확인 메시지가 표시되어야 합니다.

예시 출력:

{
  "acknowledged": true,
  "insertedIds": {
    "0": ObjectId("660a1f5c9b8f8b1234567890"),
    "1": ObjectId("660a1f5c9b8f8b1234567891")
  }
}

다음으로 books 컬렉션을 생성합니다. 각 책 문서에서 author_id 필드는 authors 컬렉션의 해당 저자의 ObjectId를 저장합니다. 이것이 책과 저자 간의 연결을 생성합니다.

db.books.insertMany([
  {
    title: "Pride and Prejudice",
    author_id: ObjectId("660a1f5c9b8f8b1234567890"),
    year: 1813
  },
  {
    title: "1984",
    author_id: ObjectId("660a1f5c9b8f8b1234567891"),
    year: 1949
  }
]);

예시 출력:

{
  "acknowledged": true,
  "insertedIds": {
    "0": ObjectId("660b2a1c9b8f8b1234567892"),
    "1": ObjectId("660b2a1c9b8f8b1234567893")
  }
}

이제 두 개의 컬렉션을 성공적으로 생성했으며 books 컬렉션의 문서와 authors 컬렉션의 문서를 연결했습니다. 다음 단계를 위해 MongoDB 쉘을 열어 두세요.

연결된 문서 쿼리

관계 설정을 마쳤으므로 다음 단계는 단일 쿼리에서 연결된 데이터를 검색하는 것입니다. MongoDB 의 집계 프레임워크는 이 목적을 위해 $lookup 단계를 제공하며, 이는 다른 컬렉션에 대한 왼쪽 외부 조인 (left outer join) 을 수행합니다.

mongosh 쉘에 여전히 있고 library_database를 사용하고 있는지 확인하십시오.

모든 책을 가져오고 결과 내에 해당 저자 정보를 포함시키는 쿼리를 실행해 보겠습니다.

db.books.aggregate([
  {
    $lookup: {
      from: "authors",
      localField: "author_id",
      foreignField: "_id",
      as: "author_details"
    }
  }
]);

$lookup 단계는 books 컬렉션을 authors 컬렉션과 조인합니다. 매개변수를 검토해 보겠습니다.

  • from: "authors": 조인할 컬렉션을 지정합니다.
  • localField: "author_id": 입력 문서 ( books 컬렉션) 의 필드를 지정합니다.
  • foreignField: "_id": "from" 컬렉션 ( authors 컬렉션) 의 문서에서 필드를 지정합니다.
  • as: "author_details": 출력에 추가할 새 배열 필드의 이름을 지정합니다. 이 배열에는 일치하는 저자 문서가 포함됩니다.

문서 중 하나의 예시 출력:

[
  {
    "_id": ObjectId("..."),
    "title": "Pride and Prejudice",
    "author_id": ObjectId("660a1f5c9b8f8b1234567890"),
    "year": 1813,
    "author_details": [
      {
        "_id": ObjectId("660a1f5c9b8f8b1234567890"),
        "name": "Jane Austen",
        "nationality": "British"
      }
    ]
  },
  ...
]

보시다시피 author_details 필드는 저자의 전체 문서를 포함하는 배열입니다. 이 강력한 기능을 통해 애플리케이션에서 여러 쿼리를 수행할 필요 없이 포괄적인 데이터를 검색할 수 있습니다.

관련 문서 업데이트

데이터베이스의 데이터는 거의 정적이지 않습니다. 이 단계에서는 authorsbooks 컬렉션 모두에서 문서를 업데이트하는 방법을 배웁니다. 참조를 사용하기 때문에 한 곳에서 저자의 정보를 업데이트하면 해당 저자와 조인하는 모든 쿼리에서 변경 사항이 자동으로 반영됩니다.

Jane Austen 의 문서에 출생 연도를 추가해 보겠습니다. updateOne 메서드와 $set 연산자를 사용하여 전체 문서를 덮어쓰지 않고 새 필드를 추가합니다.

db.authors.updateOne(
  { name: "Jane Austen" },
  {
    $set: {
      birth_year: 1775
    }
  }
);

예시 출력:

{
  "acknowledged": true,
  "insertedId": null,
  "matchedCount": 1,
  "modifiedCount": 1,
  "upsertedCount": 0
}

이제 책의 세부 정보를 업데이트해 보겠습니다. "Pride and Prejudice"에 genre를 추가합니다.

db.books.updateOne(
  { title: "Pride and Prejudice" },
  {
    $set: {
      genre: "Romance"
    }
  }
);

두 업데이트 모두 성공했는지 확인하려면 문서를 직접 쿼리할 수 있습니다.

먼저 저자를 확인합니다.

db.authors.findOne({ name: "Jane Austen" });

그런 다음 책을 확인합니다.

db.books.findOne({ title: "Pride and Prejudice" });

해당 문서에서 새 birth_yeargenre 필드를 볼 수 있습니다. 책 문서의 참조 author_id는 변경되지 않고 링크를 유지합니다.

문서 링크 관리 및 제거

관계 관리의 마지막 부분은 삭제 처리를 하는 것입니다. 문서를 제거할 때 해당 문서를 참조하는 문서에 어떤 일이 발생하는지 고려해야 합니다. MongoDB 는 자동으로 참조 무결성 (referential integrity) 을 강제하지 않으므로, 이는 애플리케이션 수준에서 관리해야 하는 작업입니다.

먼저, 저자는 그대로 두고 책을 삭제해 보겠습니다. "1984" 책을 제거합니다.

db.books.deleteOne({ title: "1984" });

예시 출력:

{ "acknowledged": true, "deletedCount": 1 }

이제 books 컬렉션을 쿼리하면 책이 하나만 남은 것을 볼 수 있습니다. authors 컬렉션의 "George Orwell" 문서는 영향을 받지 않습니다.

이제 더 복잡한 시나리오를 고려해 보겠습니다. 저자와 해당 저자와 관련된 모든 책을 제거하는 것입니다. 이는 데이터 무결성을 유지하기 위해 여러 단계의 프로세스가 필요합니다.

먼저 저자의 ID 를 찾아 변수에 저장합니다. "Jane Austen"을 제거합니다.

const authorId = db.authors.findOne({ name: "Jane Austen" })._id;

다음으로, 이 ID 를 사용하여 해당 저자와 관련된 모든 책을 삭제합니다. 저자가 여러 권의 책을 가지고 있을 경우를 대비하여 deleteMany 명령을 사용합니다.

db.books.deleteMany({ author_id: authorId });

마지막으로 저자 문서 자체를 제거합니다.

db.authors.deleteOne({ _id: authorId });

이러한 수동적인 다단계 프로세스는 유효하지 않은 author_id 참조를 가진 "고아" 책 문서가 남지 않도록 보장합니다. 책 "Pride and Prejudice"와 저자 "Jane Austen"이 각각의 컬렉션에서 제거되었는지 확인할 수 있습니다.

이제 MongoDB 쉘을 종료할 수 있습니다.

exit

요약

이 실습에서는 MongoDB 에서 연결된 문서를 작업하는 필수 기술을 배웠습니다. authorsbooks 컬렉션을 생성하고 문서 참조를 사용하여 일대다 (one-to-many) 관계를 설정하는 것부터 시작했습니다. 그런 다음 $lookup 집계 단계를 사용하여 이러한 관련 컬렉션의 데이터를 검색하고 결합하는 방법을 연습했습니다. 또한 개별 문서를 링크를 끊지 않고 업데이트하는 방법과 마지막으로 관련 문서를 제어된 다단계 프로세스로 제거하여 데이터 무결성을 유지하기 위해 삭제를 올바르게 관리하는 방법을 배웠습니다. 이러한 기술은 더 정교하고 상호 연결된 NoSQL 데이터베이스 애플리케이션을 설계하고 구축하는 강력한 기반을 형성합니다.