Java를 사용한 Amazon DocumentDB의 인덱스 관리 - Amazon DocumentDB

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

Java를 사용한 Amazon DocumentDB의 인덱스 관리

인덱스를 사용하면 Amazon DocumentDB 컬렉션에서 데이터를 효율적으로 검색할 수 있습니다. 인덱스가 없으면 DocumentDB는 컬렉션의 모든 문서를 스캔하여 지정된 쿼리를 충족하는 결과를 반환해야 합니다. 이 주제에서는 MongoDB Java 드라이버를 사용하여 인덱스를 생성, 삭제 및 나열하는 방법에 대한 정보를 제공합니다. 또한 쿼리에서 특정 인덱스가 사용되고 있는지 확인하는 방법과 특정 인덱스를 사용하도록 Amazon DocumentDB에 힌트를 제공하는 방법에 대해서도 설명합니다.

Amazon DocumentDB는 다양한 유형의 인덱스를 지원합니다. 지원되는 모든 인덱스에 대한 포괄적인 개요는이 블로그 게시물을 참조하세요.

Java를 사용하여 인덱스 생성

MongoDB Java 드라이버를 사용하여 Amazon DocumentDB에서 인덱스를 생성하는 두 가지 메커니즘은 단일 인덱스에 대한 createIndex() 메서드 또는 여러 인덱스에 대한 createIndexes() 메서드를 runCommand()통해 ~입니다. createIndex()createIndexes() 메서드를 사용하는 한 가지 이유는 인덱스 생성과 관련된 특정 오류를 포착하여 오류 처리를 개선할 수 있기 때문입니다. 이러한 메서드를 사용하는 또 다른 이유는 MongDB Java 드라이버runCommand()가 인덱스 생성 및 조작을 위한 풍부한 지원 클래스 세트를 제공하기 때문입니다. 이러한 지원 클래스는 createIndex() 또는 createIndexes() 메서드를 사용하는 경우에만 사용할 수 있습니다. 다음 세 가지 지원 클래스가 있습니다.

  • Indexes -이 클래스는 다양한 유형의 인덱스를 생성하기 위한 정적 팩토리 메서드를 제공하는 유틸리티 클래스 역할을 합니다. 복잡한 인덱스 정의를 생성하는 프로세스를 간소화하며 일반적으로 다른 인덱스 관련 클래스와 함께 사용됩니다.

  • IndexModel - 인덱스 키 정의와 해당 옵션을 모두 캡슐화하는 기본 클래스입니다. 이는 인덱싱할 항목(키)과 인덱싱 방법( 옵션)을 결합한 전체 인덱스 사양을 나타냅니다. 이 클래스는 createIndexes() 여러 인덱스를 동시에 생성할 때 특히 유용합니다. 메서드에 전달할 수 있는 인덱스 사양 모음을 정의할 수 있기 때문입니다.

  • IndexOptions - 인덱스 동작을 사용자 지정하기 위한 다양한 방법을 제공하는 포괄적인 구성 클래스입니다. 여기에는 고유 인덱스, 희소 인덱스, 만료 시간(TTL) 및 부분 필터 표현식에 대한 설정이 포함됩니다. 메서드 체인을 통해 백그라운드 인덱스 구축 및 고유한 제약 조건과 같은 여러 옵션을 구성할 수 있습니다.

단일 인덱스 생성

이 예제에서는 백그라운드에서 createIndex() 메서드를 사용하여 단일 인덱스를 생성하는 방법을 보여줍니다. 배경 및 포그라운드 인덱스 생성을 이해하려면 섹션을 참조하세요인덱스 빌드 유형. 다음 코드 예제에서는 IndexOptions를 사용하여 백그라운드에서 이름이 “unique_restaurantId_idx”인 고유 인덱스를 생성합니다. 그러면이 IndexOptions 객체가 createIndex() 메서드로 전달됩니다.

collection.createIndex( Indexes.ascending("restaurantId"), new IndexOptions() .unique(true) .name("unique_restaurantId_idx") .background(true));

여러 인덱스 생성

이 예제에서는 createIndexes() 메서드를 사용하여 여러 인덱스를 생성합니다. 먼저 IndexModel 객체를 사용하여 각 인덱스에 대한 옵션을 빌드한 다음 IndexModel 객체 목록을 createIndexes() 메서드에 전달합니다. 다음 코드 예제에서는 Indexes 유틸리티 클래스를 사용하여 복합 인덱스를 생성하는 방법을 보여줍니다. 이 클래스는 오름차순 또는 내림차순 정렬 순서를 사용하여 인덱스를 생성할지 여부를 지정하는 데에도 사용됩니다. 여러 인덱스를 생성한 후 listIndexes() 메서드를 호출하여 인덱스 생성을 확인합니다.

// Single Field Index on cuisine IndexModel singleIndex = new IndexModel( Indexes.ascending("cuisine"), new IndexOptions().name("cuisine_idx")); // Compound Index IndexModel compoundIndex = new IndexModel( Indexes.compoundIndex( Indexes.ascending("address.state"), Indexes.ascending("priceRange")), new IndexOptions().name("location_price_idx")); // Build a list of IndexModel for the indexes List < IndexModel > indexes = Arrays.asList( singleIndex, compoundIndex ); collection.createIndexes(indexes); // Verify created indexes collection.listIndexes().forEach(index - > System.out.println("Created index: " + index.toJson()));

희소 인덱스 및 부분 인덱스 생성

이 예제에서는 각 인덱스 유형에 IndexModel 대해를 생성하여 희소 인덱스와 부분 인덱스를 생성합니다.

// Sparse Index Model, this will identify only those documents that have a // michelin star rating IndexModel sparseIndex = new IndexModel( Indexes.ascending("michelin.star"), new IndexOptions() .name("michelin_sparse_idx") .sparse(true)); // Partial Index Model where the restaurant is active and has a rating of 4 and above IndexModel partialIndex = new IndexModel( Indexes.ascending("rating.average"), new IndexOptions() .name("high_rated_active_idx") .partialFilterExpression( Filters.and( Filters.eq("isActive", true), Filters.gte("rating.average", 4.0))));

텍스트 인덱스 생성

이 예제에서는 텍스트 인덱스를 생성하는 방법을 보여줍니다. 컬렉션에는 하나의 텍스트 인덱스만 허용되지만 하나의 텍스트 인덱스는 여러 필드를 포함하는 복합 인덱스일 수 있습니다. 텍스트 인덱스에서 여러 필드를 사용하는 경우 인덱스의 각 필드에 가중치를 할당할 수도 있습니다. 배열 필드의 텍스트 인덱스는 Amazon DocumentDB에서 지원되지 않으며 복합 텍스트 인덱스에 최대 30개의 필드를 사용할 수 있지만 세 개의 필드만 가중치를 할당할 수 있습니다.

IndexModel textIndex = new IndexModel( new Document() .append("name", "text") .append("description", "text") .append("cuisine", "text"), new IndexOptions() .name("restaurant_text_idx") .weights(new Document() .append("name", 10) // Restaurant name gets highest weight .append("description", 5) // Description get medium weight .append("cuisine", 2) // Cuisine type gets low weight )); collection.createIndex(textIndex.getKeys(), textIndex.getOptions());

를 사용하여 인덱스 생성 runCommand()

Amazon DocumentDB는 병렬 인덱스 생성을 지원하여 인덱스를 생성하는 데 걸리는 시간을 줄입니다. 병렬 인덱싱은 여러 동시 작업자를 사용합니다. 인덱스 생성에 사용되는 기본 작업자는 2개입니다. 이 블로그 게시물은 병렬 인덱싱에 대한 심층적인 설명을 제공합니다. 현재 MongDB Java 드라이버는 createIndex() 또는를 사용할 때 작업자 옵션 지정을 지원하지 createIndexes() 않으므로 작업자를 지정하는 유일한 방법은를 통하는 것입니다runCommand. 다음 코드 예제에서는를 사용하여 작업자를 4runCommand개로 늘리는 인덱스를 생성하는 방법을 보여줍니다.

Document command = new Document("createIndexes", "Restaurants") .append("indexes", Arrays.asList( new Document("key", new Document("name", 1)) .append("name", "restaurant_name_idx") .append("workers", 4) // Specify number of workers )); Document commendResult = connectedDB.runCommand(command);

인덱스 삭제

MongoDB Java 드라이버는 인덱스를 삭제하는 여러 방법을 제공하여 다양한 시나리오와 기본 설정에 맞게 조정할 수 있습니다. 이름, 키 사양 또는 모든 인덱스를 한 번에 삭제할 수 있습니다. 컬렉션 객체에서 메서드 dropIndex() 및를 호출하여 인덱스를 삭제할 dropIndexes() 수 있습니다. 이름으로 인덱스를 삭제할 때는 특히 복합 또는 자동 생성된 인덱스의 경우 항상 직관적이지 않을 수 있는 올바른 인덱스 이름을 사용해야 합니다. 존재하지 않는 인덱스를 삭제하려고 하면가 발생합니다MongoCommandException. default _id 인덱스는 컬렉션 내에서 문서 고유성을 보장하기 때문에 삭제할 수 없습니다.

다음 코드 예제에서는 인덱스가 생성되는 필드 이름을 제공하거나 모든 인덱스를 삭제하여 인덱스를 삭제하는 방법을 보여줍니다.

String indexName = "unique_restaurantId_idx"; Document keys = new Document("cuisine", 1); // Drop index by name collection.dropIndex(indexName); // Drop index by keys collection.dropIndex(keys); // Drop all indexes collection.dropIndexes();

여러 키를 사용하여 인덱스를 삭제할 때는 지정된 모든 키가 포함된 복합 인덱스가 있고 키 순서가 올바른지 확인합니다. 위의 인덱스 생성 예제 코드는 "cuisine" 및 기능에 대한 복합 키를 보여줍니다. 해당 복합 키를 삭제하려고 하지만 순서가 생성에 사용된 순서가 아닌 경우 MongoCommnadException 오류는 다음과 같이 발생합니다.

Document keys = new Document("features", 1) .append("cuisine", 1); try { // Drop index by keys collection.dropIndex(keys); System.out.println("Successfully dropped index with keys: " + keys.toJson()); } catch (MongoCommandException commErr) { System.out.println("Error dropping index: " + commErr.getErrorMessage()); throw new RuntimeException("MongoCommandException was thrown while dropping index", commErr); }

다음 오류가 표시됩니다.

Error dropping index: Cannot drop index: index not found. Tests run: 3, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 0.819 sec <<< FAILURE! com.amazon.docdb.guide.DocDBGuideTest.testindexGuide() Time elapsed: 0.817 sec <<< FAILURE! org.opentest4j.AssertionFailedError: Unexpected exception thrown: java.lang.RuntimeException: MongoCommandException was thrown while dropping index

인덱스 선택 결정 및 인덱스 힌트 제공

Amazon DocumentDB의 설명 기능을 사용하는 것은 쿼리 성능 및 인덱스 사용량을 이해하는 데 매우 중요합니다. 쿼리를 실행할 때 explain() 메서드를 추가하여 사용 중인 인덱스를 포함하여 쿼리 계획에 대한 자세한 정보를 얻을 수 있습니다. explain() 출력은 쿼리 실행 단계, 검사된 문서 수, 각 단계에 소요된 시간에 대한 인사이트를 제공합니다. 이 정보는 특정 인덱스가 효과적으로 사용되고 있는지 또는 쿼리가 다른 인덱스 구조의 이점을 누릴 수 있는지 식별하는 데 매우 중요합니다.

explain() 메서드는 find() 메서드와 함께 연결할 수 있습니다. explain() 메서드는 ExplainVerbosity에서 반환되는 세부 수준을 결정하는 선택적 열거형을 사용할 수 있습니다explain(). 현재 DocumentDB에서는 EXECUTION_STATSQUERY_PLANNER 열거자만 지원됩니다. 다음 코드 예제에서는 특정 쿼리에 대한 쿼리 플래너를 가져오는 방법을 보여줍니다.

// Query we want to analyze Document query = new Document() .append("cuisine", "Thai") .append("rating.average", new Document("$gte", 4.0)); Document allPlansExplain = collection.find(query).explain(ExplainVerbosity.QUERY_PLANNER); System.out.println("All Plans Explain:\n" + allPlansExplain.toJson());

쿼리 플래너 세부 수준에 대해 다음 JSON 문서가 반환됩니다.

{ "queryPlanner": { "plannerVersion": 1, "namespace": "ProgGuideData.Restaurants", "winningPlan": { "stage": "IXSCAN", "indexName": "cuisine_idx", "direction": "forward" } }, "serverInfo": { "host": "guidecluster3", "port": 27017, "version": "5.0.0" }, "ok": 1, "operationTime": { "$timestamp": { "t": 1739221668, "i": 1 } } }

Amazon DocumentDB가 특정 인덱스를 사용하도록 영향을 미치거나 강제하는 몇 가지 옵션이 있습니다. hint()hintString() 메서드를 사용하면 쿼리에 사용할 인덱스를 명시적으로 지정하여 쿼리 최적화 프로그램의 기본 인덱스 선택 동작을 재정의할 수 있습니다. DocumentDB의 쿼리 옵티마이저는 일반적으로 인덱스 선택에 적합한 선택이지만 왜곡된 데이터를 처리하거나 인덱스 성능을 테스트하는 등 특정 인덱스를를 통해 강제 적용hint()하거나 유용할 hintString() 수 있는 시나리오가 있습니다.

다음 코드 예제에서는 위 코드에서 실행된 동일한 쿼리에 복합 인덱스 “cuisine_features_idx”를 강제로 사용합니다.

// Query we want to analyze Document query = new Document() .append("cuisine", "Thai") .append("rating.average", new Document("$gte", 4.0)); List < Document > queryDocs = new ArrayList < > (); collection.find(query).hintString("cuisine_features_idx").forEach(doc - > queryDocs.add(doc));