Expiration date on a Spring Data MongoDB CompoundIndex












0















For one of our customers we have to generate a product catalog based on files provided by the client. So far we have stored the data in MongoDB via Morphia though are switching to Spring-Data-MongoDB (version 2.0.9) now.



In order to keep track of the changes done to products we keep the previous version of a product in a separate collection in order to provide some before and after view. To avoid code duplication the code basically inherits from the actual product. We agreed to store the previous version up to 90 days and afterwards we are eligible to remove it from our db.



The problem now is, that one of the fields (lastChange) was specified previously in Morphia as index with expiration day. Due to PreviousProduct inheriting this field from Product we have to use @CompoundIndex to create an index that way. Since Spring Data 1.6, however, defining an expiration timestamp on a compound index got removed.



Code-wise this looks as such:




Abstract base class:




@EqualsAndHashCode(exclude={"creationDate", "lastChange", "version"})
public abstract class MongoBaseEntity {

@Id
@Getter @Setter
protected String id;

@Getter
@DiffIgnore
protected Date creationDate;
@Getter
@DiffIgnore
protected Date lastChange;

@Version
@DiffIgnore
@Getter
protected Long version;

/**
* Do not invoke. This method will be invoked by a custom {@link
* AbstractMongoEventListerner} listening for an {@link BeforeConvertEvent}
*/
// @PrePersist
public void prePersist() {
creationDate = (creationDate == null) ? new Date() : creationDate;
lastChange = (lastChange == null) ? creationDate : new Date();
}

@Override
public abstract String toString();
}



Product class




// @Entity(value = "product", noClassnamesStored = true)
// @Indexes(@Index(fields = @Field("ownerUuid")))
@Document(collection = "product")
@Getter
@Setter
public class Product extends MongoBaseEntity {

private String ean; // european article number
private String upc; // universal product code
private string gpc; // gloabal product classification code
@Indexed
private String ownerUuid;
private String ownerName;
...
}



PreviousProduct class




// @Entity(value = "product-prev", noClassnamsStored = true)
// @Indexes({
// @Index(fields = @Field("lastChange"), options = @IndexOptions(expireAfterSeconds = 7775000)), // 90 days
// ...
// })
@Document(collection = "product-prev")
@CompoundIndexes({
@CompoundIndex(name = "expIdx_lastChange", def = "{ 'lastChange': 1 }"), // expireAfterSeconds = 7775000 (90 days)
...
}
@Getter
@Setter
@ToString
public class PreviousProduct extends ProductEntity {
...
}


I kept the previous Morphia annotations in for clarity. Note further that there are multiple compound indices on the previous product though I omitted them as they are not part of the problem here IMO.



I do understand why the support of the field was removed, as potentially one could have attempted to specify an expiry timestamp on multiple fields, when MongoDB only supports expiration on a single field only, though, in this case the expiration should only be applied on a single field.



So, how can I define an expiration index on PreviousProduct in this case so that the document stored in PreviousProduct will be removed after 90 days?










share|improve this question



























    0















    For one of our customers we have to generate a product catalog based on files provided by the client. So far we have stored the data in MongoDB via Morphia though are switching to Spring-Data-MongoDB (version 2.0.9) now.



    In order to keep track of the changes done to products we keep the previous version of a product in a separate collection in order to provide some before and after view. To avoid code duplication the code basically inherits from the actual product. We agreed to store the previous version up to 90 days and afterwards we are eligible to remove it from our db.



    The problem now is, that one of the fields (lastChange) was specified previously in Morphia as index with expiration day. Due to PreviousProduct inheriting this field from Product we have to use @CompoundIndex to create an index that way. Since Spring Data 1.6, however, defining an expiration timestamp on a compound index got removed.



    Code-wise this looks as such:




    Abstract base class:




    @EqualsAndHashCode(exclude={"creationDate", "lastChange", "version"})
    public abstract class MongoBaseEntity {

    @Id
    @Getter @Setter
    protected String id;

    @Getter
    @DiffIgnore
    protected Date creationDate;
    @Getter
    @DiffIgnore
    protected Date lastChange;

    @Version
    @DiffIgnore
    @Getter
    protected Long version;

    /**
    * Do not invoke. This method will be invoked by a custom {@link
    * AbstractMongoEventListerner} listening for an {@link BeforeConvertEvent}
    */
    // @PrePersist
    public void prePersist() {
    creationDate = (creationDate == null) ? new Date() : creationDate;
    lastChange = (lastChange == null) ? creationDate : new Date();
    }

    @Override
    public abstract String toString();
    }



    Product class




    // @Entity(value = "product", noClassnamesStored = true)
    // @Indexes(@Index(fields = @Field("ownerUuid")))
    @Document(collection = "product")
    @Getter
    @Setter
    public class Product extends MongoBaseEntity {

    private String ean; // european article number
    private String upc; // universal product code
    private string gpc; // gloabal product classification code
    @Indexed
    private String ownerUuid;
    private String ownerName;
    ...
    }



    PreviousProduct class




    // @Entity(value = "product-prev", noClassnamsStored = true)
    // @Indexes({
    // @Index(fields = @Field("lastChange"), options = @IndexOptions(expireAfterSeconds = 7775000)), // 90 days
    // ...
    // })
    @Document(collection = "product-prev")
    @CompoundIndexes({
    @CompoundIndex(name = "expIdx_lastChange", def = "{ 'lastChange': 1 }"), // expireAfterSeconds = 7775000 (90 days)
    ...
    }
    @Getter
    @Setter
    @ToString
    public class PreviousProduct extends ProductEntity {
    ...
    }


    I kept the previous Morphia annotations in for clarity. Note further that there are multiple compound indices on the previous product though I omitted them as they are not part of the problem here IMO.



    I do understand why the support of the field was removed, as potentially one could have attempted to specify an expiry timestamp on multiple fields, when MongoDB only supports expiration on a single field only, though, in this case the expiration should only be applied on a single field.



    So, how can I define an expiration index on PreviousProduct in this case so that the document stored in PreviousProduct will be removed after 90 days?










    share|improve this question

























      0












      0








      0








      For one of our customers we have to generate a product catalog based on files provided by the client. So far we have stored the data in MongoDB via Morphia though are switching to Spring-Data-MongoDB (version 2.0.9) now.



      In order to keep track of the changes done to products we keep the previous version of a product in a separate collection in order to provide some before and after view. To avoid code duplication the code basically inherits from the actual product. We agreed to store the previous version up to 90 days and afterwards we are eligible to remove it from our db.



      The problem now is, that one of the fields (lastChange) was specified previously in Morphia as index with expiration day. Due to PreviousProduct inheriting this field from Product we have to use @CompoundIndex to create an index that way. Since Spring Data 1.6, however, defining an expiration timestamp on a compound index got removed.



      Code-wise this looks as such:




      Abstract base class:




      @EqualsAndHashCode(exclude={"creationDate", "lastChange", "version"})
      public abstract class MongoBaseEntity {

      @Id
      @Getter @Setter
      protected String id;

      @Getter
      @DiffIgnore
      protected Date creationDate;
      @Getter
      @DiffIgnore
      protected Date lastChange;

      @Version
      @DiffIgnore
      @Getter
      protected Long version;

      /**
      * Do not invoke. This method will be invoked by a custom {@link
      * AbstractMongoEventListerner} listening for an {@link BeforeConvertEvent}
      */
      // @PrePersist
      public void prePersist() {
      creationDate = (creationDate == null) ? new Date() : creationDate;
      lastChange = (lastChange == null) ? creationDate : new Date();
      }

      @Override
      public abstract String toString();
      }



      Product class




      // @Entity(value = "product", noClassnamesStored = true)
      // @Indexes(@Index(fields = @Field("ownerUuid")))
      @Document(collection = "product")
      @Getter
      @Setter
      public class Product extends MongoBaseEntity {

      private String ean; // european article number
      private String upc; // universal product code
      private string gpc; // gloabal product classification code
      @Indexed
      private String ownerUuid;
      private String ownerName;
      ...
      }



      PreviousProduct class




      // @Entity(value = "product-prev", noClassnamsStored = true)
      // @Indexes({
      // @Index(fields = @Field("lastChange"), options = @IndexOptions(expireAfterSeconds = 7775000)), // 90 days
      // ...
      // })
      @Document(collection = "product-prev")
      @CompoundIndexes({
      @CompoundIndex(name = "expIdx_lastChange", def = "{ 'lastChange': 1 }"), // expireAfterSeconds = 7775000 (90 days)
      ...
      }
      @Getter
      @Setter
      @ToString
      public class PreviousProduct extends ProductEntity {
      ...
      }


      I kept the previous Morphia annotations in for clarity. Note further that there are multiple compound indices on the previous product though I omitted them as they are not part of the problem here IMO.



      I do understand why the support of the field was removed, as potentially one could have attempted to specify an expiry timestamp on multiple fields, when MongoDB only supports expiration on a single field only, though, in this case the expiration should only be applied on a single field.



      So, how can I define an expiration index on PreviousProduct in this case so that the document stored in PreviousProduct will be removed after 90 days?










      share|improve this question














      For one of our customers we have to generate a product catalog based on files provided by the client. So far we have stored the data in MongoDB via Morphia though are switching to Spring-Data-MongoDB (version 2.0.9) now.



      In order to keep track of the changes done to products we keep the previous version of a product in a separate collection in order to provide some before and after view. To avoid code duplication the code basically inherits from the actual product. We agreed to store the previous version up to 90 days and afterwards we are eligible to remove it from our db.



      The problem now is, that one of the fields (lastChange) was specified previously in Morphia as index with expiration day. Due to PreviousProduct inheriting this field from Product we have to use @CompoundIndex to create an index that way. Since Spring Data 1.6, however, defining an expiration timestamp on a compound index got removed.



      Code-wise this looks as such:




      Abstract base class:




      @EqualsAndHashCode(exclude={"creationDate", "lastChange", "version"})
      public abstract class MongoBaseEntity {

      @Id
      @Getter @Setter
      protected String id;

      @Getter
      @DiffIgnore
      protected Date creationDate;
      @Getter
      @DiffIgnore
      protected Date lastChange;

      @Version
      @DiffIgnore
      @Getter
      protected Long version;

      /**
      * Do not invoke. This method will be invoked by a custom {@link
      * AbstractMongoEventListerner} listening for an {@link BeforeConvertEvent}
      */
      // @PrePersist
      public void prePersist() {
      creationDate = (creationDate == null) ? new Date() : creationDate;
      lastChange = (lastChange == null) ? creationDate : new Date();
      }

      @Override
      public abstract String toString();
      }



      Product class




      // @Entity(value = "product", noClassnamesStored = true)
      // @Indexes(@Index(fields = @Field("ownerUuid")))
      @Document(collection = "product")
      @Getter
      @Setter
      public class Product extends MongoBaseEntity {

      private String ean; // european article number
      private String upc; // universal product code
      private string gpc; // gloabal product classification code
      @Indexed
      private String ownerUuid;
      private String ownerName;
      ...
      }



      PreviousProduct class




      // @Entity(value = "product-prev", noClassnamsStored = true)
      // @Indexes({
      // @Index(fields = @Field("lastChange"), options = @IndexOptions(expireAfterSeconds = 7775000)), // 90 days
      // ...
      // })
      @Document(collection = "product-prev")
      @CompoundIndexes({
      @CompoundIndex(name = "expIdx_lastChange", def = "{ 'lastChange': 1 }"), // expireAfterSeconds = 7775000 (90 days)
      ...
      }
      @Getter
      @Setter
      @ToString
      public class PreviousProduct extends ProductEntity {
      ...
      }


      I kept the previous Morphia annotations in for clarity. Note further that there are multiple compound indices on the previous product though I omitted them as they are not part of the problem here IMO.



      I do understand why the support of the field was removed, as potentially one could have attempted to specify an expiry timestamp on multiple fields, when MongoDB only supports expiration on a single field only, though, in this case the expiration should only be applied on a single field.



      So, how can I define an expiration index on PreviousProduct in this case so that the document stored in PreviousProduct will be removed after 90 days?







      java spring-data-mongodb






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Nov 23 '18 at 14:01









      Roman VottnerRoman Vottner

      5,74612438




      5,74612438
























          0






          active

          oldest

          votes











          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53448106%2fexpiration-date-on-a-spring-data-mongodb-compoundindex%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          0






          active

          oldest

          votes








          0






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes
















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53448106%2fexpiration-date-on-a-spring-data-mongodb-compoundindex%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          Berounka

          Sphinx de Gizeh

          Different font size/position of beamer's navigation symbols template's content depending on regular/plain...