MongoDB에서 인덱스를 적용하는 방법

MongoDB는 도큐먼트형 데이타베이스이기 때문에, 조금 다른 인덱스가 존재이다. 이번에는 RDB에 없는 인덱스의 개념에 대해 알아보겠다.

MongoDB의 색인

MongoDB에서는 기본적으로 _id 속성이 고유 인덱스로 문서를 만들 때마다 자동으로 생성된다. 이것으로 부족한 경우는 독자적으로 db.collection.createIndex()를 사용해 인덱스 작성한다. db.collection.createIndex()를 이용해 만들어지는 인덱스는 B-tree 데이터 구조의 인덱스이다.

MongoDB는 간단한 키 지정 외에도 몇 가지 인덱스 유형을 지원한다. 구체적으로 지원하는 인덱스 유형은 다음과 같다.

  • 단일 키
  • 복합 키
  • 멀티키
  • 지리
  • 텍스트
  • 해시

“복합 키"와 “멀티 키"는 명칭이 비슷하지만 내용은 다르다. “복합 키"는 “복수 필드를 조합한 키"로 하고, “멀티 키"는 “배열을 다루는 속성에 대해 그 배열에 포함되는 값 모두 대상으로 하는 키"로 하는 것이다.

이하에서는 기본이 되는 “단일 키 인덱스”, “복합 키 인덱스”, “멀티 키 인덱스"에 대해서 그 구체적인 사용법을 샘플 코드를 통해서 알아보자.

인덱스 기본 생성

mongo 쉘에서 다음 명령을 실행하여 지정된 콜렉션에 대해 인덱스를 생성할 수 있다.

JavaScript 코드에서도 함수는 동일하지만, 세번째 인수에 콜백을 지정할 수 있다는 점이 다르다.

구문

db.collection.createIndex(keys, options)

인수

인수 Type 설명
keys string/object 값이 있는 필드 이름을 지정한다. 오름차순의 키이면 1를 내림차순의 키이면 -1을 지정한다.
options object 인덱스 생성에 대한 옵션을 지정한다. 옵션으로 지정할 수 있는 것은 다음과 같다. (unique, collation) (이 밖에도 더 있지만 여기에서는 이거만 기억하자)

사용 예

아래에서 “단일 키 인덱스(Single field index)”, “복합 키 인덱스(Compound index)”, “멀티 키 인덱스(Multi-key index)“의 사용 예를 살펴 보겠다.

단일 키 색인 생성

아래와 같은 샘플 도큐먼트에 인덱스를 작성하는 샘플 코드를 3가지 다룬다. MongoDB는 도큐먼트형 데이터베이스이므로, RDB에는 없는 “내장 필드"나 “내장 도큐먼트"에 대한 인덱스 생성을 할 수 있다.

{
  "score": 1034,
  "location": { city: "Seoul", county: "Korea Republic of" }
}

단일 필드

가장 간단한 “단일 필드"에 대한 인덱스 생성에 대한 샘플 코드이다.

> db.collection.createIndex({ score: 1 })
> db.collection.find({ score: 1034 })
> db.collection.find({ score: { $gt: 1000 } })

내장 필드

MongoDB는 속성 값으로 도큐먼트를 지정할 수도 있다. 이러한 경우, 도큐먼트 내의 필드(중첩된 요소)에 대해서도 인덱스 할 수가 있다.

> db.collection.createIndex({ "location.city": 1 })
> db.collection.find({ "location.city": "Kyunggi" })

내장 도큐먼트

위에 “내장 필드"와 비슷하지만, 원래 객체를 지정할 수도 있다. 다만, 이 경우는 속성의 수와 속성의 순서를 포함해 완전 일치하는 것이 요구되는 점에 주의해야 한다.

> db.collection.createIndex({ location: 1 })
> db.collection.find({ city: "Seoul", county: "Korea Republic of" })

복합 키 색인 생성

RDB에도 존재하는 복합 키 인덱스이다. MongoDB에서는 여러 필드를 키로 지정하여 만들 수 있다. MongoDB의 복합 키 인덱스 에서는 “지정된 복합 키 모두에 일치한다"패턴 뿐만이 아니라, “일부에 일치하는” 패턴에서도 인덱스가 유효하다.

다음 샘플 데이터에 대해 “복합 키 인덱스"를 만드는 샘플을 살펴 보겠다.

{
  "item": "Apple",
  "location": "xxx store",
  "stock": 4,
  "type": "cases"
}
> db.collection.createIndex({ item: 1, location: 1, stock: 1 })
> db.collection.find({ item: "Apple" })
> db.collection.find({ item: "Apple", location: "xxx store" })
> db.collection.find({ item: "Apple", location: "xxx store", stock: { $gt: 0 } })

위에 예에서 인덱스의 작성이 item → loation → stock이므로, 그 앞에 일부가 되는 item이나 item → location등도 인덱스가 유효하다.

멀티 키 색인 생성

MongoDB에는 배열을 값으로 사용하는 필드도 있다. 배열의 값은 “프리미티브” 또는 “객체"의 어느쪽이든 “멀티키 인덱스"를 작성할 수 있다.

이하에서는 배열 필드 ratings를 포함한 콜렉션에 대해서 인덱스를 작성, 검색하는 샘플을 살펴봅니다.

{ "item": "Apple",  ratings: [ 2, 9 ] }
{ "item": "Banana", ratings: [ 4, 3 ] }

인덱스 생성은 단순히 ratings의 반대로 createIndex() 호출하여 생성할 수 있다.

> db.collection.createIndex({ ratings: 1 })

배열 필드에 대한 검색은 보통 $elemMatch을 사용한다. 아래의 예제에서는 “3 이상 6 이하 ratings가 1 레코드 이상 존재하는 문서"를 추출하고 있다.

> db.collection.find({ ratings: { $elemMatch: { $gte: 3, $lte: 6 } } })
{ "_id" : ObjectId("5a2d24459c684f917e3ec0c2"), "item" : "XYZ", "ratings" : [ 4, 3 ] }

아래와 같은 입력하게 되면 “3 이상 또는 6 이하를 만족하는 레코드가 1건 이상 존재하는 문서"를 추출하므로, 결과적으로 모두 추출되어 버린다.

> db.collection.find({ ratings: { $gte: 3, $lte: 6 } })
{ "_id" : ObjectId("5a2d24399c684f917e3ec0c1"), "item" : "ABC", "ratings" : [ 2, 9 ] }
{ "_id" : ObjectId("5a2d24459c684f917e3ec0c2"), "item" : "XYZ", "ratings" : [ 4, 3 ] }

참고 문서