Spring Solr: Using Custom Converters to Serialize object to Json String in Solr


The Problem
There are two kinds of data when save data to Solr: fields that we will search on, other fields that we will never search on.

Schemaless design
We can save all non-searchable fields to one Json string field into Solr, this way, we don't have to change Solr schema every time we add/remove a field.

We want to use object in java class, serialize it to json stirng when save to Solr, and deserialize the json string to object when read from Solr.

Solution:
As we use Spring Solr to save and restore data to/from Solr, all we need to do is implement and register custom solr converters that will convert object to json string when save to Solr, convert json string to object when read data from Solr.

We store the following Message data in Solr:
Class Message {
  long id;
  // searchable fields such as activeDate, city etc
  MessageDetails details;
}

MessageDetails implements Jsonable, Serializable {
  // all non-searchable fields define here.
}

//Mark interface: this instance will be serialized to json string when save to Solr.
public interface Jsonable {}

The 
Solr Converters
Then we will implement Solr Converters like below.
JsonableToStringConverter will convert the object into string; StringToMessageDetailsConverter will convert string instance to MessageDetails.
public class Converters {
  @WritingConverter
  public enum JsonableToStringConverter implements Converter<Jsonable, String> {
      INSTANCE;
      @Override
      public String convert(final Jsonable source) {
          if (source == null) {
              return null;
          }
          final ObjectMapper mapper = new ObjectMapper();

          try {
              return mapper.writeValueAsString(source);
          } catch (final JsonProcessingException e) {
              logger.error(MessageFormat.format("Unable to serialize to json; source: {0}", source), e);
              throw new BusinessException(ErrorCode.INTERNAL_ERROR, "Unable to serialize to json.");
          }
      }
  }

  @ReadingConverter
  public enum StringToMessageDetailsConverter implements Converter<String, MessageDetails> {
      INSTANCE;

      @Override
      public MessageDetails convert(final String source) {
          if (source == null) {
              return null;
          }
          try {
              return new ObjectMapper().readValue(source, MessageDetails.class);
          } catch (final IOException e) {
              logger.error(MessageFormat.format("Unable to deserialize from json; source: {0}", source), e);
              throw new BusinessException(ErrorCode.INTERNAL_ERROR, "Unable to deserialize from json.");
          }
      }
  }
}
At last we will register these customer converters into SolrConverter.
  @Bean
  public static SolrConverter mappingSolrConverter() {
      final MappingContext<? extends SolrPersistentEntity<?>, SolrPersistentProperty> mappingContext =
              new SimpleSolrMappingContext();
      final MappingSolrConverter converter = new MappingSolrConverter(mappingContext);
      final List<Object> converters = new ArrayList<Object>();

      converters.add(JsonableToStringConverter.INSTANCE);
      converters.add(StringToMessageDetailsConverter.INSTANCE);        
      converter.setCustomConversions(new CustomConversions(converters));
      return converter;
  }

Labels

adsense (5) Algorithm (69) Algorithm Series (35) Android (7) ANT (6) bat (8) Big Data (7) Blogger (14) Bugs (6) Cache (5) Chrome (19) Code Example (29) Code Quality (7) Coding Skills (5) Database (7) Debug (16) Design (5) Dev Tips (63) Eclipse (32) Git (5) Google (33) Guava (7) How to (9) Http Client (8) IDE (7) Interview (88) J2EE (13) J2SE (49) Java (186) JavaScript (27) JSON (7) Learning code (9) Lesson Learned (6) Linux (26) Lucene-Solr (112) Mac (10) Maven (8) Network (9) Nutch2 (18) Performance (9) PowerShell (11) Problem Solving (11) Programmer Skills (6) regex (5) Scala (6) Security (9) Soft Skills (38) Spring (22) System Design (11) Testing (7) Text Mining (14) Tips (17) Tools (24) Troubleshooting (29) UIMA (9) Web Development (19) Windows (21) xml (5)