다음을 통해 공유


Azure DocumentDB에서 인덱싱 관리

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

중요합니다

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

인덱스 형식

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

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

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

{
  "_id": ObjectId("617a34e7a867530bff1b2346"),
  "title": "Azure DocumentDB - A Game Changer",
  "content": "Azure DocumentDB 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 DocumentDB는 다음에서 인덱스 만들기를 지원합니다.

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

다음 명령은 필드 author에 단일 필드 인덱스를 생성합니다. 또한, 다음 명령은 내포된 필드 firstName에 인덱스를 생성합니다.

use cosmicworks

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

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

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

비고

Azure DocumentDB를 사용하면 컬렉션에 최대 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 DocumentDB를 사용하면 여러 필드의 조합에 텍스트 인덱스를 만들어 문서의 여러 필드에서 텍스트 검색을 수행할 수 있습니다.

텍스트 인덱스 옵션 구성

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

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

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

비고

클라이언트가 "DocumentDB"라는 용어로 텍스트 검색 쿼리를 수행하는 경우 컬렉션의 각 문서에 대한 점수는 "제목" 및 "콘텐츠" 필드 모두에서 용어의 현재 상태와 빈도에 따라 계산되며 가중치가 높기 때문에 "제목" 필드에 더 높은 중요도를 부여합니다.

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

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

  • DocumentDB에 대한 텍스트 검색을 수행합니다.

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

    use cosmicworks
    
    db.products.find(
    { $text: { $search: "DocumentDB" } },
    { 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 DocumentDB는 두 가지 유형의 지리 공간적 인덱스를 제공합니다.

  • 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. key 필드는 geoNear을 사용하는 경우 필수입니다.

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

다음 단계