다음을 통해 공유


Azure Cosmos DB for MongoDB vCore에서 인덱싱 관리

적용 대상: MongoDB vCore

인덱스는 컬렉션 내의 필드에 빠르게 액세스할 수 있게 하여 데이터 검색 속도를 향상시키는 구조입니다. 주로 키 필드를 기반으로 데이터에 대한 정렬된 포인터 집합을 만들어 작동합니다. Azure Cosmos DB for MongoDB vCore는 쿼리 푸시다운, 고유 제약 조건 및 분할 등 여러 컨텍스트에서 인덱스를 활용합니다.

Important

"_id" 필드는 기본적으로 인덱싱된 유일한 필드이며 필드의 최대 크기는 2 KB입니다. 성능을 최적화하기 위해 쿼리 필터 및 조건자를 기반으로 인덱스를 추가하는 것이 좋습니다.

인덱스 형식

간단한 설명을 위해 다음 설정을 사용하는 블로그 애플리케이션의 예를 살펴보겠습니다.

  • 데이터베이스 이름: cosmicworks
  • 컬렉션 이름: products

이 예제 애플리케이션은 아티클을 다음 구조의 문서로 저장합니다. 인용된 모든 예제는 이 컬렉션의 구조를 추가로 활용합니다.

{
  "_id": ObjectId("617a34e7a867530bff1b2346"),
  "title": "Azure Cosmos DB - A Game Changer",
  "content": "Azure Cosmos DB is a globally distributed, multi-model database service.",
  "author": {lastName: "Doe", firstName: "John"},
  "category": "Technology",
  "launchDate": ISODate("2024-06-24T10:08:20.000Z"),
  "published": true
}

단일 필드 인덱스

단일 필드 인덱스는 컬렉션에 있는 단일 필드의 정보를 저장합니다. 단일 필드 인덱스의 정렬 순서는 중요하지 않습니다. _id 필드는 기본적으로 인덱싱된 상태로 유지됩니다.

Azure Cosmos DB for MongoDB vCore는 다음 인덱스 생성을 지원합니다.

  • 최상위 문서 필드.
  • 포함된 문서.
  • 포함된 문서 내의 필드.

다음 명령은 필드 author에서, 다음 명령은 포함된 필드 firstName에서 단일 필드 인덱스를 만듭니다.

use cosmicworks

db.products.createIndex({"author": 1})

// indexing embedded property
db.products.createIndex({"author.firstName": -1})

사용 가능한 경우 하나의 쿼리가 여러 개의 단일 필드 인덱스를 사용할 수 있습니다.

참고 항목

Azure Cosmos DB for MongoDB vCore를 사용하면 컬렉션에 최대 64개의 인덱스를 만들 수 있습니다. 계층에 따라 요청 시 최대 300개의 인덱스 확장을 계획할 수 있습니다.

복합 인덱스

복합 인덱스는 문서 내의 여러 필드를 기반으로 효율적인 쿼리 및 정렬을 허용하여 데이터베이스 성능을 향상시킵니다. 이 최적화를 통해 전체 컬렉션을 검색할 필요가 줄어들어 데이터 검색 및 조직의 속도가 향상됩니다.

다음 명령은 authorlaunchDate 필드에 복합 인덱스를 만듭니다.

use cosmicworks

db.products.createIndex({"author":1, "launchDate":-1})

Order 필드는 인덱스의 선택성 또는 사용률에 영향을 미칩니다. find 쿼리는 만들어진 인덱스를 활용하지 않습니다.

use cosmicworks

db.products.find({"launchDate": {$gt: ISODate("2024-06-01T00:00:00.000Z")}})

제한 사항

  • 복합 인덱스 내의 최대 32개 필드\경로입니다.

부분 인덱스

인덱스에 용어를 생성할 시기를 설명하는 연결된 쿼리 필터가 있는 인덱스입니다.

use cosmicworks

db.products.createIndex (
   { "author": 1, "launchDate": 1 },
   { partialFilterExpression: { "launchDate": { $gt: ISODate("2024-06-24T10:08:20.000Z") } } }
)

제한 사항

  • 부분 인덱스는 필터 자격이 없는 한 ORDER BY 또는 UNIQUE를 지원하지 않습니다.

텍스트 인덱스

텍스트 인덱스는 텍스트 기반 쿼리를 최적화하여 더 빠르고 효율적으로 만드는 특수 데이터 구조입니다.

createIndex 메서드를 text 옵션과 함께 사용하여 title 필드에 텍스트 인덱스를 만듭니다.

use cosmicworks;

db.products.createIndex({ title: "text" })

참고 항목

컬렉션당 하나의 텍스트 인덱스만 정의할 수 있지만 Azure Cosmos DB for MongoDB vCore를 사용하면 여러 필드 조합에 텍스트 인덱스를 만들어 문서의 여러 필드에서 텍스트 검색을 수행할 수 있습니다.

텍스트 인덱스 옵션 구성

Azure Cosmos DB for MongoDB vCore의 텍스트 인덱스에는 동작을 사용자 지정하는 몇 가지 옵션이 제공됩니다. 예를 들어 텍스트 분석 언어를 지정하고, 가중치를 설정하여 특정 필드의 우선 순위를 지정하고, 대/소문자를 구분하지 않는 검색을 구성할 수 있습니다. 다음은 옵션을 사용하여 텍스트 인덱스 만들기의 예입니다.

  • 영어 지원을 통해 titlecontent 필드 모두에 대한 검색을 지원하는 인덱스를 만듭니다. 또한 검색 결과에서 우선순위를 지정하기 위해 title 필드에 더 높은 가중치를 할당합니다.

    use cosmicworks
    
    db.products.createIndex(
        { title: "text", content: "text" },
        { default_language: "english", weights: { title: 10, content: 5 }, caseSensitive: false }
    )
    

참고 항목

클라이언트가 "Cosmos DB"라는 용어로 텍스트 검색 쿼리를 수행하는 경우 컬렉션의 각 문서에 대한 점수는 "title" 및 "content" 필드 모두에서 용어의 존재 및 빈도에 따라 계산되며, 가중치가 높기 때문에 "title" 필드에 더 높은 중요도를 부여합니다.

텍스트 인덱스로 텍스트 검색 수행

텍스트 인덱스가 만들어지면 쿼리에서 "text" 연산자를 사용하여 텍스트 검색을 수행할 수 있습니다. text 연산자는 검색 문자열을 가져와 텍스트 인덱스와 대조하여 관련 문서를 찾습니다.

  • Cosmos DB 구문에 대한 텍스트 검색을 수행합니다.

    use cosmicworks
    
    db.products.find(
      { $text: { $search: "Cosmos DB" } }
    )
    
  • 필요에 따라 쿼리에 $meta 프로젝션 연산자를 textScore 필드와 함께 사용하여 가중치를 확인합니다.

    use cosmicworks
    
    db.products.find(
    { $text: { $search: "Cosmos DB" } },
    { score: { $meta: "textScore" } }
    )
    

제한 사항

  • 컬렉션에 하나의 텍스트 인덱스만 정의할 수 있습니다.
  • 텍스트 인덱스는 간단한 텍스트 검색을 지원하며 정규식 같은 고급 검색 기능을 아직 제공하지 않습니다.
  • 정렬 작업은 MongoDB에서 텍스트 인덱스의 순서를 사용할 수 없습니다.
  • Hint()는 $text 식을 사용하는 쿼리와 함께 지원되지 않습니다.
  • 텍스트 인덱스는 상대적으로 클 수 있으며 다른 인덱스 유형에 비해 상당한 스토리지 공간을 사용할 수 있습니다.

와일드카드 인덱스

단일 필드의 인덱스는 동일한 수준에 있는 다른 필드를 제외하고 field 아래의 모든 경로를 인덱싱합니다. 예를 들면 다음과 같은 샘플 설명서입니다.

{
 "children":
    {
     "familyName": "Merriam",
     "pets": { "details": {“name”: "Goofy", ”age”: 3} }
   } 
}

{ "pets.$**": 1 }에 인덱스를 만들면 세부 정보 및 하위 문서 속성에 인덱스가 만들어지지만 "familyName"에 인덱스가 만들어지지는 않습니다.

제한 사항

  • 와일드카드 인덱스는 고유 인덱스를 지원할 수 없습니다.
  • 와일드카드 인덱스는 와일드카드에 있는 경로 표시만 필터에 포함되지 않는 한 ORDER BY의 푸시다운을 지원하지 않습니다(와일드카드 인덱스는 정의되지 않은 요소를 인덱싱하지 않기 때문입니다).
  • 복합 와일드카드 인덱스에는 one 와일드카드 용어 및 one 또는 더 많은 인덱스 용어만 포함될 수 있습니다. { "pets.$**": 1, “familyName”: 1 }

지리 공간적 인덱스

지리 공간적 인덱스는 GeoJSON 개체 또는 레거시 좌표 쌍으로 저장된 데이터에 쿼리를 지원합니다. 지리 공간적 인덱스를 사용하여 지리 공간적 데이터의 쿼리 성능을 향상시키거나 특정 지리 공간적 쿼리를 실행할 수 있습니다.

Azure Cosmos DB for MongoDB vCore는 두 가지 유형의 지리 공간적 인덱스를 제공합니다.

  • 2dsphere 인덱스는 구의 기하 도형을 해석하는 쿼리를 지원합니다.
  • 2d 인덱스는 평면의 기하 도형을 해석하는 쿼리를 지원합니다.

2d 인덱스

2d 인덱스는 지리 공간적 데이터를 저장하는 레거시 좌표 쌍 스타일에서만 지원됩니다.

createIndex 메서드를 2d 옵션과 함께 사용하여 location 필드에 지리 공간적 인덱스를 만듭니다.

db.places.createIndex({ "location": "2d"});

제한 사항

  • one 위치 필드만 2d 인덱스의 일부가 될 수 있으며 다른 비지리 공간적 one 필드만 compound 2d 인덱스 db.places.createIndex({ "location": "2d", "non-geospatial-field": 1 / -1 })의 일부가 될 수 있습니다.

2dsphere 인덱스

2dsphere 인덱스는 지구와 유사한 구에서 지리 공간적 쿼리를 지원합니다. GeoJSON 개체 또는 레거시 좌표 쌍을 모두 지원할 수 있습니다. 2dSphere 인덱스는 데이터를 저장하는 GeoJSON 스타일을 사용하여 작동합니다. 레거시 지점이 발견되면 GeoJSON 지점으로 변환됩니다.

createIndex 메서드를 2dsphere 옵션과 함께 사용하여 location 필드에 지리 공간적 인덱스를 만듭니다.

db.places.createIndex({ "location": "2dsphere"});

2dsphere 인덱스를 사용하면 여러 지리 공간적 데이터 필드와 비지리 공간적 데이터 필드에 인덱스를 만들 수 있습니다. db.places.createIndex({ "location": "2d", "non-geospatial-field": 1 / -1, ... "more non-geospatial-field": 1 / -1 })

제한 사항

  • 일반 인덱스와 지리 공간적 인덱스를 사용하는 복합 인덱스는 지원되지 않습니다. 지리 공간적 인덱스 중 하나를 만들면 오류가 발생합니다.

    // Compound Regular & 2dsphere indexes are not supported yet
    db.collection.createIndex({a: 1, b: "2dsphere"})
    
    // Compound 2d indexes are not supported yet
    db.collection.createIndex({a: "2d", b: 1})
    
  • 구멍이 있는 다각형에서는 작동하지 않습니다. 다음 시나리오에서는 $geoWithin 쿼리가 실패하지만 구멍이 있는 다각형 삽입은 제한되지 않습니다.

    1. 쿼리 자체에 구멍이 있는 다각형이 포함된 경우

      coll.find(
        {
            "b": {
                "$geoWithin": {
                    "$geometry": {
                        "coordinates": [
                            [
                                [ 0, 0], [0, 10], [10, 10],[10,0],[0, 0]
                            ],
                            [
                                [5, 5], [8, 5], [ 8, 8], [ 5, 8], [ 5, 5]
                            ]
                        ],
                        "type": "Polygon"
                    }
                }
            }
        })
      
      // MongoServerError: $geoWithin currently doesn't support polygons with holes
      
    2. 구멍이 있는 다각형을 포함한 필터링되지 않은 문서가 있는 경우

      [mongos] test> coll.find()
        [
          {
            _id: ObjectId("667bf7560b4f1a5a5d71effa"),
            b: {
              type: 'Polygon',
              coordinates: [
                [ [ 0, 0 ], [ 0, 10 ], [ 10, 10 ], [ 10, 0 ], [ 0, 0 ] ],
                [ [ 5, 5 ], [ 8, 5 ], [ 8, 8 ], [ 5, 8 ], [ 5, 5 ] ]
              ]
            }
          }
        ]
      // MongoServerError: $geoWithin currently doesn't support polygons with holes
      
    3. geoNear를 사용하는 동안 key 필드는 필수입니다.

       [mongos] test> coll.aggregate([{ $geoNear: { $near: { "type": "Point", coordinates: [0, 0] } } }])
      
       // MongoServerError: $geoNear requires a 'key' option as a String
      

다음 단계