问题描述
我正在使用MongoDB和Java。 我有Mongo 3.0.1 Java驱动程序。 我创建了一个集合,该集合上有一个带有expireAfter属性的TTL索引。 如果我尝试修改该值,则代码将出现错误:
'exception: Index with name: created_1 already exists with different options'
因此,在决定是否删除索引并为其创建新版本之前,我想检查索引是否存在,并检查索引的expireAfter属性。
MongoCollection对象只有listIndexes方法,该方法返回一个集合。 获取索引并检查expireAfter属性的最佳方法是什么?
这是首先创建索引的代码。 当我更改EXPIRATION_DAYS常量的值并重新运行代码时,将发生问题:
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);
1楼
您无法在MongoDB中更新索引。 您必须先删除现有索引,然后使用其他选项重新创建它。
我建议您使用特定名称创建索引。 这样,您可以遍历现有索引并删除有问题的索引,然后再重新创建它。
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);
2楼
根据 ,修改现有索引的唯一方法是删除索引并重新创建。
如果要获取特定索引而不遍历列表,可以在system.indexes
集合上使用findOne
:
DBObject index = database.getCollection("system.indexes")
.findOne(new BasicDBObject("name", "created_1"));
如果不存在这样的索引,那么您将获得null
否则您将能够读取expireAfterSeconds
属性-秒,而不是天。
3楼
根据 ,自v2.2起,您已经能够在Mongo shell中运行以下命令:
db.runCommand({collMod: "<collection-name>",
index : { keyPattern: { "<indexed-field>": 1 },
expireAfterSeconds: <new-value> }})
转换为使用 ,您将获得:
Document collModCmd =
Document.parse("{collMod: '<collection-name>', " +
" index : { keyPattern: {'<indexed-field>': 1}, " +
" expireAfterSeconds: <new-value> }}");
Document commandResult = db.runCommand(collModCmd);
似乎对我的测试收集工作正常。