Springboot and MongoDB: Creating indices on inherited properties or fields.

I started writing my first spring and the first springboot application today. The project requires mongodb and mysql as databases. My application’s domain objects are highly hierarchical and we need to make different kinds of search engines for many child classes. So, there needs to be some violations from common patterns like “field shadowing”. Though it’s only for the purpose of data and search layer, it doesn’t affect the object model of the application. So, I needed to change field behavior in subclasses which are different entities or collections in Mongo store. Basically I needed to put a annotation on subclass to enable an index on a field.

Here is one of the ways you can put and index to a field which is a  property of a super class. The base class is taken from “getting started mongo db example from STS”. So far, you cannot directly annotate an inherited field, and can partially annotation getter or setters. But those does not work with “index” annotation on sub-class.

package com.test.mongo;

import org.springframework.data.annotation.Id;

public class Customer {

    @Id
    private String id;

    private String firstName;
    private String lastName;

    public Customer() {}

    public Customer(String firstName, String lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }

    @Override
    public String toString() {
        return String.format(
                "Customer[id=%s, firstName='%s', lastName='%s']",
                id, firstName, lastName);
    }

}

As you can see the base class doesn’t index on firstName. Now I am going to create a PremiumCustomer class which will be persisted in its own collection. And I need to create a index on “firstName”. Here goes the code

package com.test.mongo;

import org.springframework.data.mongodb.core.index.CompoundIndex;
import org.springframework.data.mongodb.core.index.CompoundIndexes;
import org.springframework.data.mongodb.core.mapping.Document;

@Document
@CompoundIndexes(

@CompoundIndex( name = "fName", def = "{ 'firstName' : 1 }" )

)
public class PremiumCustomer extends Customer {

    public PremiumCustomer() {
        super();
        // TODO Auto-generated constructor stub
    }

    public PremiumCustomer( String firstName, String lastName ) {
        super( firstName, lastName );
        // TODO Auto-generated constructor stub
    }

}

I tried creating a setter in the derived class annotating it with @Index which didn’t work. But @CompoundIndexes works like a charm! And the effect is a “single index” as we created it on a single field only.

One important thing I found that in spring 1.4.2 which is the latest stable version at the time being, that without @Document annotation, @CompoundIndexes annotation is not processed at all. So, it’s safe to annotate classes which to be persisted with @Document annotation.

@CompoundIndexes does not work without @Document annotation

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s