Search code examples
javamongodbspring-dataazure-cosmosdbttl

AzureDocumentDB MongoDB protocol support: Failing to create TTL index


I'm currently using Spring Data MongoDB to abstract MongoDB operations, and using an Azure DocumentDB database with MongoDB protocol support. I've also run into this using the latest MongoDB Java driver by itself.

There is an issue with setting a TTL index in this process.

I'm receiving the following exception.

`Caused by: com.mongodb.CommandFailureException: { "serverUsed" : "****-****-test.documents.azure.com:****" , "_t" : "OKMongoResponse" , "ok" : 0 , "code" : 2 , "errmsg" : "The 'expireAfterSeconds' option has invalid value. Ensure to provide a nonzero positive integer, or '-1'` which means never expire." , "$err" : "The 'expireAfterSeconds' option has invalid value. Ensure to provide a nonzero positive integer, or '-1' which means never expire."}
at com.mongodb.CommandResult.getException(CommandResult.java:76)
at com.mongodb.CommandResult.throwOnError(CommandResult.java:140)
at com.mongodb.DBCollectionImpl.createIndex(DBCollectionImpl.java:399)
at com.mongodb.DBCollection.createIndex(DBCollection.java:597)

This is a simple representation of the POJO that I'm using.

public class Train{
   @JsonProperty
   private String id;

   @JsonProperty("last_updated")
   @Indexed(expireAfterSeconds = 1)
   private Date lastUpdated;

   // Getters & Setters
   .
   .
   .
}

This was my initial approach of initializing the index (via the @Indexed annotation).

I've also attempted to initialize the index via:

mongoTemplate.indexOps(collection.getName())
                .ensureIndex(new Index("last_updated", Sort.Direction.DESC)
                .expire(1, TimeUnit.SECONDS));

Both ways of setting the index throw that same execption.

I've also seen an error saying that it can only be done on the '_ts' field. I think this is due to Azure DocumentDB using the '_ts' field for it's own TTL operation. So I've tried the following with the same results:

  • Added a new field, Long '_ts', to the pojo and tried with the annotation.
  • Attempted to set the index via the ensureIndex method with '_ts' field.
  • Did the same things above but changing the type of '_ts' to Date.

I'm new to these technologies (DocumentDB and MongoDB), so I'm probably missing something obvious.

Any thoughts?


Solution

  • Revisiting my question I had posted a while back to reply with the solution that I figured out.

    Note that DocumentDB has been renamed to CosmosDB since I posted this question.

    There was an issue with type casting in either the Spring framework or the CosmosDB/DocumentDB platform side. Despite documentation saying it needs an integer, you actually need to pass it a double value.

    I'm using something along the lines of the following and it works

    dcoll.createIndex(new BasicDBObject("_ts", 1)
                        , new BasicDBObject("expireAfterSeconds", 10.0));