package gov.nysenate.openleg.dao.bill.search; import com.google.common.collect.Lists; import gov.nysenate.openleg.client.view.bill.BillView; 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.bill.BaseBillId; import gov.nysenate.openleg.model.bill.Bill; 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.rescore.RescoreBuilder; 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.Collections; import java.util.List; import java.util.stream.Collectors; @Repository public class ElasticBillSearchDao extends ElasticBaseDao implements BillSearchDao { private static final Logger logger = LoggerFactory.getLogger(ElasticBillSearchDao.class); protected static final String billIndexName = SearchIndex.BILL.getIndexName(); protected static final List<HighlightBuilder.Field> highlightedFields = Arrays.asList(new HighlightBuilder.Field("basePrintNo").numOfFragments(0), new HighlightBuilder.Field("printNo").numOfFragments(0), new HighlightBuilder.Field("title").numOfFragments(0)); /** {@inheritDoc} */ @Override public SearchResults<BaseBillId> searchBills(QueryBuilder query, QueryBuilder postFilter, RescoreBuilder.Rescorer rescorer, List<SortBuilder> sort, LimitOffset limOff) { SearchRequestBuilder searchBuilder = getSearchRequest(billIndexName, query, postFilter, highlightedFields, rescorer , sort, limOff, false); SearchResponse response = searchBuilder.execute().actionGet(); logger.debug("Bill search result with query {} took {} ms", query, response.getTookInMillis()); return getSearchResults(response, limOff, this::getBaseBillIdFromHit); } /** {@inheritDoc} */ @Override public void updateBillIndex(Bill bill) { updateBillIndex(Collections.singletonList(bill)); } /** {@inheritDoc} */ @Override public void updateBillIndex(Collection<Bill> bills) { if (!bills.isEmpty()) { BulkRequestBuilder bulkRequest = searchClient.prepareBulk(); List<BillView> billViewList = bills.stream().map(BillView::new).collect(Collectors.toList()); billViewList.forEach(b -> bulkRequest.add( searchClient.prepareIndex(billIndexName, Integer.toString(b.getSession()), b.getBasePrintNo()) .setSource(OutputUtils.toJson(b))) ); safeBulkRequestExecute(bulkRequest); } } /** {@inheritDoc} */ @Override public void deleteBillFromIndex(BaseBillId baseBillId) { if (baseBillId != null) { deleteEntry(billIndexName, Integer.toString(baseBillId.getSession().getYear()), baseBillId.getBasePrintNo()); } } /** * {@inheritDoc} */ @Override protected List<String> getIndices() { return Lists.newArrayList(billIndexName); } protected BaseBillId getBaseBillIdFromHit(SearchHit hit) { return new BaseBillId(hit.getId(), Integer.parseInt(hit.getType())); } }