부분 인덱스는 지정된 필터 표현식을 충족하는 컬렉션의 문서만 인덱싱합니다. 컬렉션에 있는 문서의 하위 집합을 인덱싱하면 부분 인덱스의 스토리지 요구 사항이 줄어들고 인덱스 생성 및 유지 관리에 드는 성능 비용이 절감됩니다.
부분 인덱스 생성하기
partial 인덱스를 생성하려면 partialFilterExpression 옵션과 함께 db.collection.createIndex() 메서드를 사용합니다. partialFilterExpression 옵션은 다음을 사용하여 필터 조건을 지정하는 문서를 허용합니다.
등식 표현식(예
field: value또는$eq연산자 사용)$exists: true표현식$type표현식$and연산자$or연산자$in연산자$geoWithin연산자$geoIntersects연산자
예시 들어 genre 필드 Drama인 문서만 인덱싱하는 복합 인덱스 만듭니다.
db.movies.createIndex( { title: 1 }, { partialFilterExpression: { genres: "Drama" } } )
모든 MongoDB 인덱스 유형에 partialFilterExpression 옵션을 지정할 수 있습니다. 시계열 컬렉션의 TTL 인덱스에 partialFilterExpression를 지정하는 경우 컬렉션의 metaField에 대해서만 필터링할 수 있습니다.
팁
MongoDB Compass에서 인덱스를 관리하는 방법을 알아보려면 인덱스 관리를 참조하세요.
행동
쿼리 적용 범위
MongoDB는 인덱스를 사용하여 불완전한 결과 집합이 생성되는 경우 쿼리 또는 정렬 작업에 부분 인덱스를 사용하지 않습니다.
부분 인덱스를 사용하려면 쿼리가 필터 표현식 (또는 필터 표현식의 부분 집합을 지정하는 수정된 필터 표현식)을 쿼리 조건의 일부로 포함해야 합니다.
예를 들어 다음 인덱스가 있다고 가정해 보겠습니다.
db.users.createIndex( { name: 1 }, { partialFilterExpression: { password: { $exists: true } } } )
쿼리 조건자에는 인덱스 필터하다 표현식 password: { $exists: true
}과 일치하는 문서와 일치하는 조건 password: { $exists: true } 가 포함되어 있으므로 다음 쿼리 인덱스 를 사용할 수 있습니다.
db.users.find( { name: "Ned Stark", password: { $exists: true } } )
그러나 다음 쿼리 인덱스 를 사용하면 불완전한 결과 설정하다 되므로 name 필드 의 부분 인덱스 사용할 수 없습니다. 구체적으로, 쿼리 조건자에는 조건 password: { $exists: false } 이(가) 포함되는 반면 인덱스 password: { $exists:
true } 필터하다 있습니다. 즉, { name: "Ned Stark", password: { $exists: false }
} 쿼리 인덱스 가 포함하는 것보다 더 많은 문서(비밀번호가 없는 사용자)와 일치합니다.
db.users.find( { name: "Ned Stark", password: { $exists: false } } )
마찬가지로, 다음 쿼리는 쿼리 조건자에 필터 표현식이 포함되어 있지 않고 인덱스를 사용하면 불완전한 결과 집합이 반환되기 때문에 부분 인덱스를 사용할 수 없습니다.
db.users.find( { name: "Ned Stark" } )
Sparse 인덱스와 비교
인덱스 할 문서를 보다 정확하게 제어하려면 희소 인덱스 보다 부분 인덱스를 사용하세요.
희소 인덱스는 인덱싱된 필드 (또는 희소 복합 인덱스의 경우 여러 필드)의 존재 여부만을 기준으로 문서를 포함하거나 제외합니다.
부분 인덱스는 필터하다 표현식 에 따라 문서를 포함하거나 제외합니다. 표현식 인덱스 키 이외의 필드가 포함될 수 있으며, 기존 필드 이외의 조건을 지정할 수 있습니다.
예시 를 들어, 부분 인덱스 희소 인덱스 와 동일한 동작을 구현 수 있습니다. 이 부분 인덱스 name 필드 에서 희소 인덱스 와 동일한 쿼리를 지원합니다.
db.users.createIndex( { name: 1 }, { partialFilterExpression: { name: { $exists: true } } } )
그러나 부분 인덱스 인덱스 키 이외의 필드도 필터하다 할 수 있습니다. 예시 를 들어 name 필드 의 부분 인덱스 email 필드 의 존재 여부를 확인할 수 있습니다.
db.users.createIndex( { name: 1 }, { partialFilterExpression: { email: { $exists: true } } } )
쿼리 옵티마이저가 이 부분 인덱스를 선택하려면 쿼리 조건이 name 필드에 대한 조건을 포함해야 하며 email 필드에 대해 null이 아닌 일치도 포함해야 합니다.
예를 들어, 다음 쿼리는 name 필드에 대한 조건과 email 필드에 대한 null이 아닌 일치 항목을 모두 포함하므로 인덱스를 사용할 수 있습니다.
db.users.find( { name: "Ned Stark", email: { $regex: /gameofthron\.es$/ } } )
그러나 다음 쿼리는 필터 표현식 { email: { $exists: true } }에서 허용되지 않는 email 필드에 null 일치를 포함하고 있기 때문에 인덱스를 사용할 수 없습니다.
db.users.find( { name: "Ned Stark", email: { $exists: false } } )
부분 TTL 인덱스
부분 인덱스는 TTL 인덱스일 수도 있습니다. 부분 TTL 인덱스는 지정된 필터 표현식과 일치하며 해당 문서만 만료됩니다. 자세한 내용은 필터 조건이 있는 문서 만료를 참조하세요.
제한 사항
partialFilterExpression옵션과sparse옵션을 모두 지정할 수 없습니다._id인덱스는 부분 인덱스가 될 수 없습니다.샤드 키 인덱스는 부분 인덱스가 될 수 없습니다.
클라이언트 사이드 필드 수준 암호화 또는 Queryable Encryption을 사용하는 경우
partialFilterExpression은 암호화된 필드를 참조할 수 없습니다.
동등한 인덱스
MongoDB 7.3 부터는 데이터 정렬을 사용하는 동일한 인덱스 키와 동일한 부분 표현식을 가진 부분 인덱스를 생성할 수 없습니다.
기존의 동등한 인덱스가 있는 MongoDB 7.3 데이터베이스의 경우 인덱스는 유지되지만 첫 번째 동등한 인덱스만 쿼리에 사용됩니다. 이는 MongoDB 7.3 이전 버전과 동일한 동작입니다.
예시 를 들어 부분 필터하다 표현식 에서는 텍스트의 대소문자만 다른 두 개의 인덱스를 만들 수 없습니다.
예시
이 페이지의 예제에서는 sample_mflix 샘플 데이터 세트의 데이터를 사용합니다. 이 데이터 세트를 자체 관리형 MongoDB deployment 에 로드하는 방법에 대한 자세한 내용은 샘플 데이터 세트 로드를 참조하세요. 샘플 데이터베이스를 수정한 경우 이 페이지의 예제를 실행 하려면 데이터베이스를 삭제하고 다시 만들어야 할 수 있습니다.
컬렉션에 대한 부분 인덱스 만들기
다음 예시 title 및 genres 필드에 부분 인덱스 추가합니다. 이 작업은 rating 필드 PG인 문서만 인덱싱합니다.
db.movies.createIndex( { title: 1, genres: 1 }, { partialFilterExpression: { rated: "PG" } } )
movies 컬렉션 에 대한 다음 쿼리 부분 인덱스 사용하여 "삼총사"라는 제목의 모든 영화의 작가를 반환합니다.
db.movies.find( { title: "The Three Musketeers", genres: ["Action", "Adventure", "Comedy"], rated: "PG" }, { writers: 1 } )
그러나 다음 쿼리 쿼리 조건자에 rating 필터하다 포함되어 있지 않으므로 부분 인덱스 사용할 수 없습니다.
db.movies.find( { genres: "Drama" }, { title: 1 } ).limit(5)
Unique 제약 조건이 있는 부분 인덱스
부분 인덱스는 지정된 필터 표현식을 충족하는 컬렉션의 문서만 인덱싱합니다. partialFilterExpression과 고유 (Unique) 제약 조건을 모두 지정하는 경우 고유 제약 조건은 필터 표현식을 충족하는 문서에만 적용됩니다. 고유 제약 조건이 있는 부분 인덱스는 문서가 필터 기준을 충족하지 않는 경우 고유 제약 조건을 충족하지 않는 문서의 삽입을 막지 않습니다.
컬렉션 에 대한 다음 작업은 users 필드 에 고유한 제약 조건을 지정하는 인덱스 와 부분 필터하다 email 표현식 를 password: { $exists: true } 생성합니다.
db.users.createIndex( { name: 1 }, { name: "name_partial_unique_idx", unique: true, partialFilterExpression: { password: { $exists: true } } } )
인덱스 는 컬렉션 에 이미 존재하는 이메일 주소와 기존 password 필드 모두 포함된 문서의 삽입을 방지합니다.
그러나 고유 제약 조건은 password 필드 있는 문서에만 적용되므로 중복 이메일 주소가 있는 다음 문서는 허용됩니다.
db.users.insertMany( [ // This document does NOT have a password field, so it's NOT indexed // The unique constraint does not apply to it { name: "Jon Snow", email: "jon1@example.com" }, // This document has a password field, so it IS indexed // The unique constraint applies to it { name: "Sansa Stark", email: "sansa@example.com", password: "password123" }, // This document does NOT have a password field, so it's NOT indexed // We can insert it even though it has the same name as the first document // This demonstrates that the unique constraint only applies to indexed documents { name: "Jon Snow", email: "jon2@example.com" } ] )