NoSQL_01 MongoDB

aggapang·2025년 6월 7일

kb IT's Your Life

목록 보기
17/20

1장 MongoDB

  • 웹 어플리케이션과 인터넷 기반에 적합한 데이터베이스 관리 시스템
  • 직관적인 데이터 모델
    • 값을 여러개 입력 가능

도큐먼튼

  • JSON에 기반 -> key-value로 구성
  • 테이블 간 조인 연산 X
  • 대부분의 정보를 하나의 document로 표현
  • 객체 지향 언어의 객체에 잘 매핑이 됨

도큐먼트 모델

  • 속성의 이름과 값으로 이루어진 쌍의 집합
  • 고정된 스키마 X -> 다양한 구조의 데이터 표현
    • 어플리케이션 기반 데이터 구조 결정
    • 개발 초기 빈번한 데이터 구조 변경에도 불구하고 개발 속도 단축됨
    • 가변적 속성을 갖는 데이터 표현 가능
  • 내부적으로 Binary JSON or BSON 형태로 저장
  • 컬렉션(collection)에 도큐먼트 저장

인덱스

  • B-Tree 기반
  • _id 프라이머리 키에 대해 자동으로 인덱스 생성
  • 세컨더리 인덱스 생성 가능
  • 컬렉션 별 64개 인덱스 생성 가능

복제(replica)

샤팅(shading)

  • 범위 기반 파티션 메커니즘을 통해 자동으로 여러 노드를 분산
  • 수직적 확장
  • 수평적 확장

2장 자바스크립트 셸

데이터베이스

use 데이터베이스명

  • 여러 개의 컬렉션을 담고 있는 상위 네임스페이스(namespace) 개념
  • RDBMS의 “스키마”와 유사한 역할
  • 현재 사용 중인 데이터베이스는 db라는 전역 변수에 설정됨

컬렉션

  • Collection
  • 도큐먼트(Document)들의 집합체
  • RDBMS에서의 “테이블(table)”과 거의 동일한 개념

도큐먼트

  • JSON 혹은 BSON(Binary JSON) 형태의 구조화된 데이터 한 덩어리
  • 내부에 키(key)–값(value) 쌍
  • 하위 문서를 중첩(Nested) 구조로 포함하는 것도 가능
  • 모든 도큐먼트는 _id 필드 기본으로 가짐
    • 명시적으로 지정하지 않으면 MongoDB가 자동으로 ObjectId 타입의 유니크 ID를 생성

기본 CRUD 연산

  • MongoDB 자바스크립트 셸을 통해 데이터베이스에 직접 명령을 통해 CRUD 작업을 이룸

삽입(Insert) 및 조회(Find)

db.컬렉션명.메서드

// 컬렉션에 문서 저장
> db.컬렉션명.insert({ key: "value" })

// 삽입된 모든 도큐먼트 확인
> db.컬렉션명.find()

// 조건에 맞는 도큐먼트 출력
> db.컬렉션명.find(조건)

// 예시 출력
{ _id: ObjectId("4bf9bec50e32f82523389314"),  key: "value" }
  • _id 필드 : MongoDB에서 프라이머리 키 역할

업데이트(Update)

컬렉션명.update(조건, update할 것, upsert여부, 다중적용여부)

  • upsert : 해당 문서가 없는 경우 insert 할지 여부 (기본은 false)
  • 다중적용여부 : 여러개 도큐먼트를 한번에 업데이트 할지
  1. 부분 업데이트(Partial Update): $set 수정, $unset 삭제 연산자를 사용해 기존 도큐먼트의 일부 필드만 변경
  2. 대체 업데이트(Replacement): 쿼리로 조회된 도큐먼트 전체를 새로운 도큐먼트로 대체
  • $set 수정 / $unset 삭제
// username이 "smith"인 도큐먼트에 country 필드 추가
> db.users.update(
  { username: "smith" },
  { $set: { country: "Canada" } }
 )
// country 필드 삭제
> db.users.update(
  { username: "smith" },
  { $unset: { country: 1 } }
 )

// 부분 업데이트 (중첩 데이터)
> db.users.update(
  { username: "smith" },
  {
    $set: {
      favorites: {
      cities: ["Chicago", "Cheyenne"],
      movies: ["Casablanca", "The Sting"]
      }
    }
  }
 )
// 배열(Array)을 수정
// `$push` : 배열에 무조건 추가 (중복 가능)
// `$addToSet` : 중복 없이 배열에 추가
> db.users.update(
  { "favorites.movies": "Casablanca" },
  { $addToSet: { "favorites.movies": "The Maltese Falcon" } },
    false,  // upsert: 해당 도큐먼트가 없으면 새로 삽입할지 여부
    true    // multi: 여러 개의 도큐먼트를 한 번에 업데이트할지 여부
    )

삭제(Remove) 및 컬렉션 관리

컬렉션명.remove(조건)

  • 모두 삭제되어도 컬렉션은 유지
> db.users.remove(조건)
> db.users.remove({})  // 컬렉션의 모든 도큐먼트 삭제(컬렉션 자체는 유지)
  • 컬렉션 삭제:
> db.users.drop()

대용량 샘플 데이터 생성

  • 반복문 > 삽입 가능
for (let i = 0; i < 200000; i++) {
  db.numbers.save({ num: i });
}
> db.numbers.count()  // 200000

범위 쿼리

범위 연산자

연산자설명
$gt (Greater Than)~보다 큰, 초과
$gte (Greater Than or Equal)~보다 크거나 같은, 이상
$lt~보다 작은, 미만
$lte~보다 작거나 작은, 이하
// num 값이 20보다 크고 25보다 작은 도큐먼트 조회
db.items.find({ value: { $gt: 20, $lt: 25 } })

db.items.find({ value: { $gte: 97 } })  // 정수 타입 필드만 비교
db.items.find({ value: { $gte: "a" } }) // 문자열 타입 필드만 비교

집합 연산자 (Set Operators)

연산자설명
$in참고 집합에 하나라도 있는 경우 일치
$all모든 인수가 참고 집합에 있고 배열이 포함된 도큐먼트에서 사용되는 경우 일치
$nin그 어떤 인수도 참고 집합에 있지 않을 경우 일치
db.products.find({
  main_cat_id: {
    $in: [
       ObjectId("6a5b1476238d3b4dd5000048"),
       ObjectId("6a5b1476238d3b4dd5000051"),
       ObjectId("6a5b1476238d3b4dd5000057")
      ]
    }
  })

부울(Boolean) 연산자

연산자설명
$ne인수가 요소와 같지 않은 경우 일치
$not일치 결과를 반전시킴(반대로 만듦)
$or제공된 검색어 집합 중 하나라도 TRUE인 경우 일치
$nor제공된 검색어 집합 중 그 어떤 것도 TRUE가 아닌 경우 일치
$and제공된 검색어 집합이 모두 TRUE인 경우 일치
$exists요소가 도큐먼트 안에 존재할 경우 일치
// 세부 예시: details.color가 "blue" 이거나 details.manufacturer가 "ACME"인 상품 찾기
db.products.find({
  $or: [
    { "details.color": "blue" },
    { "details.manufacturer": "ACME" }
  ]
})

// AND 조건
db.products.find({
    $and: [
      {tags: {$in: ["gift", "holiday"]}},
      {tags: {$in: ["gardening", "landscaping"]}}
    ]
  })

// exist 연산자
db.products.find({ "details.color": { $exists: false } }) // 해당 키가 없는 도큐먼트
db.products.find({ "details.color": { $exists: true } })  // 해당 키가 있는 도큐먼트

배열(Array) 관련 쿼리

연산자설명
$elemMatch제공된 모든 조건이 동일한 하위 도큐먼트에 있는 경우 일치
$size배열 하위 도큐먼트의 크기가 제공된 리터럴 값과 같으면 일치
  • 배열 내부 특정 요소 검색
// tags 배열에 "soil"이라는 문자열을 포함한 도큐먼트
db.products.find({ tags: "soil" })

// tags 배열의 첫 번째(인덱스 0) 값이 "soil"인지
db.products.find({ "tags.0": "soil" })
  • 중첩(Embedded) 배열 검색
// addresses라는 배열 필드 안에 있는 객체/문서의 state 값이 "NY"인지
db.users.find({ "addresses.0.state": "NY" })
db.users.find({ "addresses.state": "NY" })  
// 배열 안 객체 필드 두 개를 모두 조건으로 걸고 싶을 때 ($elemMatch 사용)
db.users.find({
  addresses: {
    $elemMatch: {
      name: "home",
      state: "NY"
    }
  }
})

인덱스

  • 인덱스 생성 :
    컬렉션명.createIndex({키:1,...})

    • 지정한 키로 오름차순 정렬된 인덱스 생성
    • -1 로 지정하면 내림차순 정렬됨
  • 인덱스 확인 : 컬렉션명.getIndexes()

정보 얻기

조회 정보

  • explain() : 퀴리 수행 성능 조회
    • db.컬렉션명.find(조건).explain("executionStats")

데이터베이스 정보 얻기

  • show dbs : 데이터베이스 목록 보기
  • show collections : 사용 중인 데베의 커렉션 목록 보기
  • db.status() : 사용 중인 데베 상태 보기
  • db.numbers.status() : 사용 중인 컬렉션 상태 보기

3장. 쿼리 작성

페이지네이션

db.users.find({country:"Korea"}).skip(5).limit(10) : 나라가 korea인 데이터 중 5개 뒤의 10개 출력

  • skip(n) : 건너뛸 데이터 개수
  • limit(m) : 추출할 데이터 개수
  • sort({키1:1, 키2:-1,...} : 정렬

0개의 댓글