/* * Copyright (c) 2008-2014 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.mongodb.acceptancetest.index; import com.mongodb.client.DatabaseTestCase; import com.mongodb.client.MongoCollection; import com.mongodb.client.model.IndexOptions; import com.mongodb.operation.OrderBy; import org.bson.Document; import org.junit.Ignore; import org.junit.Test; import java.util.ArrayList; import java.util.List; import java.util.concurrent.TimeUnit; import static com.mongodb.operation.OrderBy.ASC; import static com.mongodb.operation.OrderBy.DESC; import static com.mongodb.operation.OrderBy.fromInt; import static org.hamcrest.CoreMatchers.notNullValue; import static org.hamcrest.CoreMatchers.nullValue; import static org.hamcrest.core.Is.is; import static org.junit.Assert.assertThat; /** * Use cases for adding indexes to your MongoDB database via the Java driver. Documents the index options that are currently supported by * the updated driver. */ public class AddIndexAcceptanceTest extends DatabaseTestCase { @Test public void shouldGetExistingIndexesOnDatabase() { collection.insertOne(new Document("new", "value")); List<Document> indexes = collection.listIndexes().into(new ArrayList<Document>()); assertThat("Should have the default index on _id when a document exists", indexes.size(), is(1)); String nameOfIndex = indexes.get(0).getString("name"); assertThat("Should be the default index on id", nameOfIndex, is("_id_")); } @Test public void shouldCreateIndexOnCollectionWithoutIndex() { collection.createIndex(new Document("field", 1)); assertThat("Should be default index and new index on the database now", collection.listIndexes().into(new ArrayList<Document>()).size(), is(2)); } @Test public void shouldCreateIndexWithNameOfFieldPlusOrder() { collection.createIndex(new Document("field", 1)); String nameOfCreatedIndex = (String) collection.listIndexes().into(new ArrayList<Document>()).get(1).get("name"); assertThat("Should be an index with name of field, ascending", nameOfCreatedIndex, is("field_1")); } @Test public void shouldCreateAnAscendingIndex() { collection.createIndex(new Document("field", 1)); Document newIndexDetails = collection.listIndexes().into(new ArrayList<Document>()).get(1); OrderBy order = fromInt((Integer) ((Document) newIndexDetails.get("key")).get("field")); assertThat("Index created should be ascending", order, is(ASC)); } @Test public void shouldCreateADescendingIndex() { collection.createIndex(new Document("field", -1)); Document newIndexDetails = collection.listIndexes().into(new ArrayList<Document>()).get(1); OrderBy order = fromInt((Integer) ((Document) newIndexDetails.get("key")).get("field")); assertThat("Index created should be descending", order, is(DESC)); } @Test public void shouldCreateNonUniqueIndexByDefault() { collection.createIndex(new Document("field", 1)); Document newIndexDetails = collection.listIndexes().into(new ArrayList<Document>()).get(1); assertThat("Index created should not be unique", newIndexDetails.get("unique"), is(nullValue())); } @Test public void shouldCreateIndexOfUniqueValues() { collection.createIndex(new Document("field", 1), new IndexOptions().unique(true)); Document newIndexDetails = collection.listIndexes().into(new ArrayList<Document>()).get(1); Boolean unique = (Boolean) newIndexDetails.get("unique"); assertThat("Index created should be unique", unique, is(true)); } @Test public void shouldSupportCompoundIndexes() { collection.createIndex(new Document("theFirstField", 1).append("theSecondField", 1)); Document newIndexDetails = collection.listIndexes().into(new ArrayList<Document>()).get(1); Document keys = (Document) newIndexDetails.get("key"); Object theFirstField = keys.get("theFirstField"); assertThat("Index should contain the first key", theFirstField, is(notNullValue())); OrderBy orderBy = fromInt((Integer) theFirstField); assertThat("Index created should be ascending", orderBy, is(ASC)); Object theSecondField = keys.get("theSecondField"); assertThat("Index should contain the second key", theSecondField, is(notNullValue())); orderBy = fromInt((Integer) theSecondField); assertThat("Index created should be ascending", orderBy, is(ASC)); assertThat("Index name should contain both field names", (String) newIndexDetails.get("name"), is("theFirstField_1_theSecondField_1")); } @Test public void shouldSupportCompoundIndexesWithDifferentOrders() { collection.createIndex(new Document("theFirstField", 1).append("theSecondField", -1)); Document newIndexDetails = collection.listIndexes().into(new ArrayList<Document>()).get(1); Document keys = (Document) newIndexDetails.get("key"); OrderBy orderBy = fromInt((Integer) keys.get("theFirstField")); assertThat("First index should be ascending", orderBy, is(ASC)); orderBy = fromInt((Integer) keys.get("theSecondField")); assertThat("Second index should be descending", orderBy, is(DESC)); assertThat("Index name should contain both field names", (String) newIndexDetails.get("name"), is("theFirstField_1_theSecondField_-1")); } @Test public void shouldOnlyReturnIndexesForTheSelectedCollection() { collection.createIndex(new Document("field", 1)); MongoCollection<Document> anotherCollection = database.getCollection("anotherCollection"); anotherCollection.createIndex(new Document("someOtherField", 1)); assertThat("Should be default index and new index on the first database", collection.listIndexes().into(new ArrayList<Document>()).size(), is(2)); assertThat("Should be default index and new index on the second database", anotherCollection.listIndexes() .into(new ArrayList<Document>()) .size(), is(2)); } @Test public void shouldBeAbleToAddGeoIndexes() { collection.createIndex(new Document("locationField", "2d")); assertThat("Should be default index and new index on the database now", collection.listIndexes().into(new ArrayList<Document>()).size(), is(2)); } @Test public void shouldBeAbleToAddGeoSphereIndexes() { collection.createIndex(new Document("locationField", "2dsphere")); assertThat("Should be default index and new index on the database now", collection.listIndexes().into(new ArrayList<Document>()).size(), is(2)); } @Test public void shouldSupportCompoundIndexesOfOrderedFieldsAndGeoFields() { collection.createIndex(new Document("locationField", "2d").append("someOtherField", 1)); Document newIndexDetails = collection.listIndexes().into(new ArrayList<Document>()).get(1); Document keys = (Document) newIndexDetails.get("key"); Object geoField = keys.get("locationField"); assertThat("Index should contain the first key", geoField, is(notNullValue())); String geoIndexValue = geoField.toString(); assertThat("Index created should be a geo index", geoIndexValue, is("2d")); Object orderedField = keys.get("someOtherField"); assertThat("Index should contain the second key", orderedField, is(notNullValue())); OrderBy orderBy = fromInt((Integer) orderedField); assertThat("Index created should be ascending", orderBy, is(ASC)); assertThat("Index name should contain both field names", (String) newIndexDetails.get("name"), is("locationField_2d_someOtherField_1")); } @Test public void shouldAllowAliasForIndex() { String indexAlias = "indexAlias"; collection.createIndex(new Document("theField", 1), new IndexOptions().name(indexAlias)); String nameOfCreatedIndex = collection.listIndexes().into(new ArrayList<Document>()).get(1).getString("name"); assertThat("Should be an index named after the alias", nameOfCreatedIndex, is(indexAlias)); } @Test public void shouldCreateASparseIndex() { collection.createIndex(new Document("theField", 1), new IndexOptions().sparse(true)); Boolean sparse = collection.listIndexes().into(new ArrayList<Document>()).get(1).getBoolean("sparse"); assertThat("Should be a sparse index", sparse, is(true)); } @Test @Ignore("Ingore until SERVER-16274 if resolved") public void shouldCreateABackgroundIndex() { collection.createIndex(new Document("theField", 1), new IndexOptions().background(true)); Boolean background = collection.listIndexes().into(new ArrayList<Document>()).get(1).getBoolean("background"); assertThat("Should be a background index", background, is(true)); } @Test public void shouldCreateATtlIndex() { collection.createIndex(new Document("theField", 1), new IndexOptions().expireAfter(1600L, TimeUnit.SECONDS)); Long ttl = collection.listIndexes().into(new ArrayList<Document>()).get(1).getLong("expireAfterSeconds"); assertThat("Should be a ttl index", ttl, is(1600L)); } //TODO: other ordering options //TODO: can you disable the index on ID for non-capped collections? }