package gov.nysenate.openleg.dao.agenda.search;
import gov.nysenate.openleg.client.view.agenda.AgendaCommFlatView;
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.agenda.Agenda;
import gov.nysenate.openleg.model.agenda.CommitteeAgendaId;
import gov.nysenate.openleg.model.agenda.AgendaId;
import gov.nysenate.openleg.model.entity.Chamber;
import gov.nysenate.openleg.model.entity.CommitteeId;
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.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;
@Repository
public class ElasticAgendaSearchDao extends ElasticBaseDao implements AgendaSearchDao
{
private static final Logger logger = LoggerFactory.getLogger(ElasticAgendaSearchDao.class);
protected static final String agendaIndexName = SearchIndex.AGENDA.getIndexName();
/** {@inheritDoc} */
@Override
public SearchResults<AgendaId> searchAgendas(QueryBuilder query, QueryBuilder postFilter,
List<SortBuilder> sort, LimitOffset limOff) {
SearchRequestBuilder searchBuilder = getSearchRequest(agendaIndexName, query, postFilter, sort, limOff);
SearchResponse response = searchBuilder.execute().actionGet();
logger.debug("Agenda Search result with query {} took {} ms", query, response.getTookInMillis());
return getSearchResults(response, limOff, this::getAgendaIdFromHit);
}
/** {@inheritDoc} */
@Override
public SearchResults<CommitteeAgendaId> searchCommitteeAgendas(QueryBuilder query, QueryBuilder postFilter,
List<SortBuilder> sort, LimitOffset limOff) {
SearchRequestBuilder searchBuilder = getSearchRequest(agendaIndexName, query, postFilter, sort, limOff);
SearchResponse response = searchBuilder.execute().actionGet();
logger.debug("Committee Agenda search result with query {} took {} ms", query, response.getTookInMillis());
return getSearchResults(response, limOff, (hit) ->
new CommitteeAgendaId(
getAgendaIdFromHit(hit), new CommitteeId(Chamber.SENATE, hit.getId()))
);
}
private AgendaId getAgendaIdFromHit(SearchHit hit) {
String[] type = hit.getType().split("-");
return new AgendaId(Integer.parseInt(type[1]), Integer.parseInt(type[0]));
}
/** {@inheritDoc} */
@Override
public void updateAgendaIndex(Agenda agenda) {
updateAgendaIndex(Collections.singletonList(agenda));
}
/** {@inheritDoc} */
@Override
public void updateAgendaIndex(Collection<Agenda> agendas) {
if (!agendas.isEmpty()) {
BulkRequestBuilder bulkRequest = searchClient.prepareBulk();
agendas.forEach(agenda ->
agenda.getCommittees().stream()
.map(cid -> new AgendaCommFlatView(agenda, cid, null))
.forEach(cfv ->
bulkRequest.add(
searchClient.prepareIndex(agendaIndexName,
agenda.getId().getYear() + "-" + cfv.getAgenda().getId().getNumber(),
cfv.getCommittee().getCommitteeId().getName())
.setSource(OutputUtils.toJson(cfv)))));
safeBulkRequestExecute(bulkRequest);
}
}
/** {@inheritDoc} */
@Override
public void deleteAgendaFromIndex(AgendaId agendaId) {
if (agendaId != null) {
deleteEntry(agendaIndexName, Integer.toString(agendaId.getYear()), Long.toString(agendaId.getNumber()));
}
}
@Override
protected List<String> getIndices() {
return Arrays.asList(agendaIndexName);
}
}