How to Map a Java Entity to Multiple MongoDB Collections in Spring Boot and use Different Indexing for both Collections?

Viewed 638

Say I have a pojo class:

public class event {
  String eventId;
  String date;
  String state;
}

And I want to save my event class in 2 separate collections in MongoDB.

I can use mongoTemplate for this:

mongoTemplate.save(event, "collection_1");
mongoTemplate.save(event, "collection_2");

But I run into problems because the collections need to have a different way of handeling the documents.

  1. The first collection should store every event as a new document. But the documents should expire after x seconds.
  2. The second collection should only store the latest entry for a given eventId.

Using annotations I can achieve 1. and 2. separately in the following way:

Criteria 1.

@Document
public class event {
  String eventId;
  @Indexed(expireAfterSeconds = x)
  String date;
  String state;
}

Criteria 2.

@Document
public class event {
  @Id
  String eventId;
  String date;
  String state;
}

I can't find a good way of achieving both criteria at the same time.

I know I could for example create 2 more classes that have the same fields as the event class but with different annotations and have a constructor that takes an event as an argument. But this really does not feel like a good solution with all the duplicate code.

Is there a more elegant solution for this problem?

1 Answers

So I finally found an awnser to my question. I'll post it here incase anyone else encounters the same problem.

The trick is to set the indexing through a configuration file instead of using annotations.

@Configuration
@DependsOn("mongoTemplate")
public class MongoCollectionConfiguration {

    private final MongoTemplate mongoTemplate;

    @Autowired
    public MongoCollectionConfiguration(MongoTemplate mongoTemplate) {
        this.mongoTemplate = mongoTemplate;
    }

    @PostConstruct
    public void initIndexes() {
        mongoTemplate.indexOps("collection_1")
            .ensureIndex(
                new Index().on("location.timestamp", Sort.Direction.DESC).expire(604800)
            );
        mongoTemplate.indexOps("collection_2")
            .ensureIndex(
                new Index().on("location.timestamp", Sort.Direction.DESC).unique()
            );    
    }

I hope this helps someone in the future, and ofcourse I am open to any improvement!

Related