/** * */ package de.bstly.board.businesslogic; import java.util.List; import javax.persistence.EntityManager; import javax.transaction.Transactional; import org.hibernate.search.engine.search.query.SearchResult; import org.hibernate.search.mapper.orm.Search; import org.hibernate.search.mapper.orm.massindexing.MassIndexer; import org.hibernate.search.mapper.orm.session.SearchSession; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.SmartInitializingSingleton; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.event.ContextRefreshedEvent; import org.springframework.context.event.EventListener; import org.springframework.stereotype.Component; import com.google.common.collect.Lists; import de.bstly.board.model.Comment; import de.bstly.board.model.Entry; import de.bstly.board.model.support.Types; /** * The Class SearchManager. */ @Component public class SearchManager implements SmartInitializingSingleton { private Logger logger = LoggerFactory.getLogger(SearchManager.class); @Autowired private EntityManager em; @Autowired private SettingsManager settingsManager; private SearchSession searchSession; /* * @see org.springframework.beans.factory.SmartInitializingSingleton# * afterSingletonsInstantiated() */ /* * @see org.springframework.beans.factory.SmartInitializingSingleton# * afterSingletonsInstantiated() */ @Override public void afterSingletonsInstantiated() { searchSession = Search.session(em); } /** * On application event. * * @param event the event */ @EventListener(ContextRefreshedEvent.class) @Transactional public void onApplicationEvent(ContextRefreshedEvent event) { MassIndexer indexer = searchSession.massIndexer().idFetchSize(150) .batchSizeToLoadObjects(25).threadsToLoadObjects(12); try { logger.info("start indexing!"); indexer.startAndWait(); logger.info("finished indexing!"); } catch (InterruptedException e) { logger.error("error on indexing!", e); Thread.currentThread().interrupt(); } } @Transactional public SearchResult search(List types, String search, int page, int size, boolean asc, boolean sortByDate) { List> classes = Lists.newArrayList(); for (Types type : types) { switch (type) { case comment: classes.add(Comment.class); break; case entry: classes.add(Entry.class); break; default: break; } } if (classes.contains(Entry.class)) { return searchSession.search(classes) .where(f -> f.bool() .should(f.match().field("title").matching(search) .boost(settingsManager.getGravity())) .should(f.match().field("title_de").matching(search) .boost(settingsManager.getGravity())) .should(f.match().field("url").matching(search)) .should(f.match().field("url_de").matching(search)) .should(f.match().field("text").matching(search)) .should(f.match().field("text_de").matching(search))) .sort(f -> sortByDate ? (asc ? f.field("created").asc() : f.field("created").desc()) : (asc ? f.score().asc() : f.score().desc())) .fetch(page * size, size); } else { return searchSession.search(classes) .where(f -> f.bool().should(f.match().field("text").matching(search)) .should(f.match().field("text_de").matching(search))) .sort(f -> sortByDate ? (asc ? f.field("created").asc() : f.field("created").desc()) : (asc ? f.score().asc() : f.score().desc())) .fetch(page * size, size); } } }