package gov.nysenate.openleg.dao.hearing.search;
import com.google.common.collect.Lists;
import gov.nysenate.openleg.client.view.hearing.PublicHearingView;
import gov.nysenate.openleg.dao.base.ElasticBaseDao;
import gov.nysenate.openleg.dao.base.LimitOffset;
import gov.nysenate.openleg.dao.base.SearchIndex;
import gov.nysenate.openleg.model.hearing.PublicHearing;
import gov.nysenate.openleg.model.hearing.PublicHearingId;
import gov.nysenate.openleg.model.search.SearchResults;
import gov.nysenate.openleg.util.OutputUtils;
import org.elasticsearch.action.bulk.BulkRequestBuilder;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.highlight.HighlightBuilder;
import org.elasticsearch.search.sort.SortBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Repository;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;
@Repository
public class ElasticPublicHearingSearchDao extends ElasticBaseDao implements PublicHearingSearchDao
{
private static final Logger logger = LoggerFactory.getLogger(ElasticPublicHearingSearchDao.class);
protected static final String publicHearingIndexName = SearchIndex.HEARING.getIndexName();
protected static final List<HighlightBuilder.Field> highlightedFields =
Arrays.asList(new HighlightBuilder.Field("text").numOfFragments(2),
new HighlightBuilder.Field("committees").numOfFragments(0),
new HighlightBuilder.Field("title").numOfFragments(0));
/** {@inheritDoc} */
@Override
public SearchResults<PublicHearingId> searchPublicHearings(QueryBuilder query, QueryBuilder postFilter,
List<SortBuilder> sort, LimitOffset limOff) {
SearchRequestBuilder searchBuilder = getSearchRequest(publicHearingIndexName, query, postFilter, highlightedFields, null, sort, limOff, false);
SearchResponse response = searchBuilder.execute().actionGet();
logger.debug("Public Hearing search result with query {} and filter {} took {} ms", query, postFilter, response.getTookInMillis());
return getSearchResults(response, limOff, this::getPublicHearingIdFromHit);
}
/** {@inheritDoc} */
@Override
public void updatePublicHearingIndex(PublicHearing publicHearing) {
updatePublicHearingIndex(Arrays.asList(publicHearing));
}
/** {@inheritDoc} */
@Override
public void updatePublicHearingIndex(Collection<PublicHearing> publicHearings) {
if (!publicHearings.isEmpty()) {
BulkRequestBuilder bulkRequest = searchClient.prepareBulk();
List<PublicHearingView> publicHearingViews = publicHearings.stream().map(PublicHearingView::new).collect(Collectors.toList());
publicHearingViews.forEach(ph ->
bulkRequest.add(searchClient.prepareIndex(publicHearingIndexName, "hearings", ph.getFilename())
.setSource(OutputUtils.toJson(ph)))
);
safeBulkRequestExecute(bulkRequest);
}
}
/** {@inheritDoc} */
@Override
public void deletePublicHearingFromIndex(PublicHearingId publicHearingId) {
if (publicHearingId != null) {
deleteEntry(publicHearingIndexName, "hearings", publicHearingId.getFileName());
}
}
/** {@inheritDoc} */
@Override
protected List<String> getIndices() {
return Lists.newArrayList(publicHearingIndexName);
}
private PublicHearingId getPublicHearingIdFromHit(SearchHit hit) {
return new PublicHearingId(hit.getId());
}
}