19

In a Python script using PyMongo, an index is created for a collection using the line

myCollection.create_index('Datetime', unique=True)

However this throws an error the next time the script is executed because the index already exist.

Question: Is there a way to check for the existance of an index before deciding whether to call create_index?

3 Answers 3

23

In PyMongo 3.6.0 and later, calling create_index will not recreate the index if it already exists and will not throw an error. The index creation will just be ignored if the index already exists.

Sign up to request clarification or add additional context in comments.

6 Comments

Are you able to cite any sources that document this behavior?
Second bullet point on the documentation
Who can deal with these unrealistic scientific standards of evidence? :) Thanks @GabrielFair, the default behavior works as detailed.
This works only for indexes that are not unique. If you already have an index that is unique, you'll get pymongo.errors.DuplicateKeyError, when calling create_index again.
My pymongo version is 3.11.3 and mongodb version is 4.4.3, but it gives pymongo.errors.OperationFailure: Index with name: {INDEX_NAME} already exists with a different name if an index with the same field exists. Does anyone have a similar problem?
|
16

You can use index_information() method:

Get information on this collection’s indexes.

Returns a dictionary where the keys are index names (as returned by create_index()) and the values are dictionaries containing information about each index.

index_name = 'Datetime'
if index_name not in myCollection.index_information():
    myCollection.create_index(index_name, unique=True)

There is also list_indexes() method which can also be used to solve it, but the output format is not that convenient as in case of index_information().

And, there is that ensure_index() method, that looks exactly what you are asking about, but this method is now deprecated.

1 Comment

The keys of the dict returned by index_information() are index names (as returned by create_index), which are different from the index keys. Are you sure your code works ? Note that it is possible to specify a custom name when creating an index.
1

This might work:

def ensure_index(conn, index):
    """
    Creates the index if it does not exist.
    Input Args:
        conn: MongoClient object, created using uri.
        index: List of index tuples. Example:
            [('age', pymongo.DESCENDING), ('sex', pymongo.ASCENDING)]
    """
    index = index or []
    index_str = '_'.join(
        map(lambda x: '%s_%s' %(x[0], x[1]), index)
    )

    indexes = conn.index_information().keys()
    if index_str and index_str not in indexes:
        conn.create_index(index, background=True)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.