package gov.nysenate.openleg.service.entity.committee.search; import com.google.common.eventbus.EventBus; import com.google.common.eventbus.Subscribe; import gov.nysenate.openleg.dao.base.LimitOffset; import gov.nysenate.openleg.dao.base.SearchIndex; import gov.nysenate.openleg.dao.entity.committee.search.ElasticCommitteeSearchDao; import gov.nysenate.openleg.model.base.SessionYear; import gov.nysenate.openleg.model.entity.CommitteeSessionId; import gov.nysenate.openleg.model.entity.CommitteeVersionId; import gov.nysenate.openleg.model.search.*; import gov.nysenate.openleg.service.base.search.ElasticSearchServiceUtils; import gov.nysenate.openleg.service.entity.committee.data.CommitteeDataService; import gov.nysenate.openleg.service.entity.committee.event.CommitteeUpdateEvent; import org.elasticsearch.ElasticsearchException; import org.elasticsearch.index.query.QueryBuilder; import org.elasticsearch.index.query.QueryBuilders; import org.elasticsearch.search.SearchParseException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import javax.annotation.PostConstruct; import java.util.Collection; @Service public class ElasticCommitteeSearchService implements CommitteeSearchService { @Autowired ElasticCommitteeSearchDao committeeSearchDao; @Autowired CommitteeDataService committeeDataService; @Autowired EventBus eventBus; @PostConstruct private void init() { eventBus.register(this); } /** * {@inheritDoc} */ @Override public SearchResults<CommitteeVersionId> searchAllCommittees(String query, String sort, LimitOffset limitOffset) throws SearchException { return searchCommittees(QueryBuilders.queryStringQuery(query), null, sort, limitOffset); } @Override public SearchResults<CommitteeVersionId> searchAllCurrentCommittees(String query, String sort, LimitOffset limitOffset) throws SearchException { return searchCommittees(QueryBuilders.queryStringQuery(query), getCurrentFilter(), sort, limitOffset); } /** * {@inheritDoc} */ @Override public SearchResults<CommitteeVersionId> searchCommitteesForSession(SessionYear sessionYear, String query, String sort, LimitOffset limitOffset) throws SearchException { return searchCommittees(QueryBuilders.queryStringQuery(query), getSessionFilter(sessionYear), sort, limitOffset); } /** * {@inheritDoc} */ @Override public SearchResults<CommitteeVersionId> searchCurrentCommitteesForSession(SessionYear sessionYear, String query, String sort, LimitOffset limitOffset) throws SearchException { QueryBuilder currentSessionFilter = QueryBuilders.boolQuery() .must(getSessionFilter(sessionYear)) .must(getCurrentFilter()); return searchCommittees(QueryBuilders.queryStringQuery(query), currentSessionFilter, sort, limitOffset); } /** * {@inheritDoc} */ @Subscribe @Override public void handleCommitteeUpdateEvent(CommitteeUpdateEvent committeeUpdateEvent) { updateIndex(committeeUpdateEvent.getCommittee().getSessionId()); } /** * {@inheritDoc} */ @Override public void updateIndex(CommitteeSessionId content) { committeeSearchDao.updateCommitteeIndex(content); } /** * {@inheritDoc} */ @Override public void updateIndex(Collection<CommitteeSessionId> content) { committeeSearchDao.updateCommitteeIndexBulk(content); } /** * {@inheritDoc} */ @Override public void clearIndex() { committeeSearchDao.purgeIndices(); committeeSearchDao.createIndices(); } /** * {@inheritDoc} */ @Override public void rebuildIndex() { clearIndex(); committeeSearchDao.updateCommitteeIndexBulk(committeeDataService.getAllCommitteeSessionIds()); } /** * {@inheritDoc} */ @Subscribe @Override public void handleRebuildEvent(RebuildIndexEvent event) { if (event.affects(SearchIndex.COMMITTEE)) { rebuildIndex(); } } /** {@inheritDoc} */ @Override @Subscribe public void handleClearEvent(ClearIndexEvent event) { if (event.affects(SearchIndex.COMMITTEE)) { clearIndex(); } } /** --- Internal Methods --- */ QueryBuilder getCurrentFilter() { return QueryBuilders.boolQuery().mustNot(QueryBuilders.existsQuery("reformed")); } QueryBuilder getSessionFilter(SessionYear sessionYear) { return QueryBuilders.termQuery("sessionYear", sessionYear.getYear()); } private SearchResults<CommitteeVersionId> searchCommittees(QueryBuilder query, QueryBuilder postFilter, String sort, LimitOffset limitOffset) throws SearchException { if (limitOffset == null) { limitOffset = LimitOffset.ALL; } try { return committeeSearchDao.searchCommittees(query, postFilter, ElasticSearchServiceUtils.extractSortBuilders(sort), limitOffset); } catch (SearchParseException ex) { throw new SearchException("There was a problem parsing the supplied query string.", ex); } catch (ElasticsearchException ex) { throw new UnexpectedSearchException(ex); } } }