I'm using MongoDB and Java. I have the Mongo 3.0.1 java driver. I have created a collection, which has a TTL index on it with an expireAfter property. If I try to amend that value then the code will error with:
'exception: Index with name: created_1 already exists with different options'
I therefore want to check if the index exists, and check the expireAfter attribute of the index, before deciding whether to drop the index and create a new version of it.
The MongoCollection object only has listIndexes method, which return a collection. What is the best way to get the index, and check the expireAfter property?
Here is the code that creates the index in the first place. The problem occurs when I change the value of the EXPIRATION_DAYS constant and rerun the code:
private static final Long EXPIRATION_DAYS = Long.valueOf(10);
....
final IndexOptions options = new IndexOptions();
options.expireAfter(EXPIRATION_DAYS, TimeUnit.DAYS);
database.getCollection(errors).createIndex(new BasicDBObject("created", 1), options);
You cannot update indexes in MongoDB. You have to drop the existing index first and then recreate it with different options.
I suggest you create the index with a specific name. This way you can iterate over the existing indexes and drop the index in question before creating it again.
private static final Long EXPIRATION_DAYS = Long.valueOf(10);
private static final String INDEX_NAME = "myIndex";
[...]
MongoCollection<Document> errorsCollection = database.getCollection(errors);
ListIndexesIterable<Document> indexes = errorsCollection.listIndexes();
for (Document index : indexes) {
if (index.getString("name").equals(INDEX_NAME) && index.getLong("expireAfterSeconds") != TimeUnit.SECONDS.convert(EXPIRATION_DAYS, TimeUnit.DAYS)) {
errorsCollection.dropIndex(INDEX_NAME);
}
}
IndexOptions options = new IndexOptions()
.name(INDEX_NAME)
.expireAfter(EXPIRATION_DAYS, TimeUnit.DAYS);
errorsCollection.createIndex(new Document("created", 1), options);
According to mongoDB docs the only way to modify an existing index is to drop it and create again.
If you want to get a specific index without looping over the list you can use findOne
on the system.indexes
collection:
DBObject index = database.getCollection("system.indexes")
.findOne(new BasicDBObject("name", "created_1"));
If no such index exists then you'll get null
otherwise you will be able to read the expireAfterSeconds
property - seconds, not days.
According to the MongoDB docs , you've been able to run a command in the Mongo shell like the following since v2.2:
db.runCommand({collMod: "<collection-name>",
index : { keyPattern: { "<indexed-field>": 1 },
expireAfterSeconds: <new-value> }})
Translating that to use the MongoDB Java driver , you get:
Document collModCmd =
Document.parse("{collMod: '<collection-name>', " +
" index : { keyPattern: {'<indexed-field>': 1}, " +
" expireAfterSeconds: <new-value> }}");
Document commandResult = db.runCommand(collModCmd);
Seems to work fine for me on a test collection.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.