I want to use mongo and ElasticSearch in my projects, and I also like adopt Spring Data Mongo and Spring Data ElasticSearch, but both has their Repository and model specs, how to use them together?
There are some options:
Use the same model class for Mongo and ElasticSearch?
@Document//from Spring Data Mongo @Document// from Spring Data ElasticSearch public class Book{ @Id//Spring Data Commons private String id; }
But there are some mismatch in Spring Data Mongo and Spring Data ElasticSearch, such as Geo field type.
Define different model for Mongo and ElasticSearch, and copy data state from Mongo model and create index when create a new model.
Any suggestion here?
I would like use option 2 in projects.
- Save mongo document as normal.
- Fire a event via JMS/AMQP/Reactor to sync the data to Elasticsearch, and choose the index strategy for every field in the ElasticSearch Document.
- All search operations are based on ElasticSearch.
Updated on 5/15/2016
I have created a sample to demo this approach.
I used Spring builtin ApplicationEvent to demo this approach.
The event publisher side, Mongo saved the post and publish an event.
@Component public class Publisher implements ApplicationEventPublisherAware { private static final Logger LOG = LoggerFactory.getLogger(Publisher.class); @Autowired PostRepository repository; private ApplicationEventPublisher publisher; public Publisher() { } public void savePost(Post post) { Post saved = repository.save(post); this.publisher.publishEvent(saved); LOG.debug("saved post data in mongo@" + saved); } @Override public void setApplicationEventPublisher(ApplicationEventPublisher publisher) { this.publisher = publisher; } }
The event receiver side, received the data and sync it into ElasticSearch storage.
@Component public class Receiver { private static final Logger LOG = LoggerFactory.getLogger(Receiver.class); @Autowired ESPostRepository repository; @EventListener public void onPostSaved(Post savedPost) { LOG.debug("=================received post data============== @\r\n"+ savedPost); ESPost doc=new ESPost(); doc.setId("1"); doc.setTitle(savedPost.getTitle()); doc.setContent(savedPost.getContent()); repository.save(doc); } }
In production environment, the publisher and receiver can be placed in different applications via JMA/AMQP instead of builtin ApplicationEvent.
The mongo is used as main storage and ElasticSearch as index/search server.