25

To create an index for a collection (as documented here https://docs.spring.io/spring-data/mongodb/docs/current/reference/html/) one can use something like the following:

mongoTemplate.indexOps(Person.class).ensureIndex(new Index().on("name",Order.ASCENDING));

But where in the program should I place this code snippet?

In the relevant repository's constructor? I've did it like that now and it works, but I somehow feel like it is bad design.

Somewhere in Mongo configuration? I haven't found a suitable method to override for that here https://docs.spring.io/spring-data/mongodb/docs/current/api/org/springframework/data/mongodb/config/AbstractMongoConfiguration.html

Maxim
  • 972
  • 2
  • 10
  • 18
  • Have you tried annotating (@Indexed) the indexed field(name) in the person pojo ? Did that not work you or may be that is not what you are looking for ? – s7vr Nov 01 '17 at 13:30
  • @Veeram That's not what I am looking for. I have two similar DB model classes, one of which extends the other, and one of these should have a compound unique index over 2 fields, while the other should only have a simple unique index over 1 field. So I've put the `@CompoundIndex` annotation for the extending class and have to add the index programmatically for the extended class. – Maxim Nov 02 '17 at 07:53
  • @Maxim did you found your answer? I have the same doubt. – Nishant Bhardwaz Jan 08 '18 at 10:09
  • @NishantBhardwaz I've just placed it in the repository's constructor in absence of a better option. – Maxim Jan 17 '18 at 08:47

2 Answers2

43

If you need to do it in programmatic way, you can just create new Spring's @Configuration and perform such initialization:

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

    @Autowired
    private MongoTemplate mongoTemplate;

    @PostConstruct
    public void initIndexes() {
        mongoTemplate.indexOps("collectionName") // collection name string or .class
            .ensureIndex(
                new Index().on("name", Sort.Direction.ASC)
        );
    }
}
Dawid Naczke
  • 1,144
  • 12
  • 11
  • will this be part of controller, service or repository files ? – fireball.1 Jul 19 '19 at 04:58
  • 2
    This is a separate class and will be called on start. – Monicka Jul 19 '19 at 05:41
  • 2
    Thanks Dawid. I found it comfortable to put this as an inner class of the interface of MongoRepository – ozma Jul 24 '19 at 09:08
  • 1
    Am I correct in assuming the annotation `@DependsOn("mongoTemplate")` is not needed in this case because the autowired dependency on `MongoTemplate` implies the `DependsOn` relationship with that spring resource? – Daniel Camarda Dec 19 '20 at 13:38
  • 1
    I recommend following this answer so that `@Index` annotations can work without needing this. https://stackoverflow.com/a/62655088/11606132 – Taimoor Ahmad Dec 27 '20 at 20:16
2

MongoDB supports compound indexes, where a single index structure holds references to multiple fields.

Let's see a quick example using compound indexes:

@QueryEntity
@Document
@CompoundIndexes({
    @CompoundIndex(name = "email_age", def = "{'email.id' : 1, 'age': 1}")
})
public class User {
    //
}