use of org.bedework.calfacade.filter.SortTerm in project bw-calendar-engine by Bedework.
the class CoreEvents method getEvents.
@Override
public Collection<CoreEventInfo> getEvents(final Collection<BwCalendar> calendars, final FilterBase filter, final BwDateTime startDate, final BwDateTime endDate, final List<BwIcalPropertyInfoEntry> retrieveList, final DeletedState delState, RecurringRetrievalMode recurRetrieval, final boolean freeBusy) throws CalFacadeException {
/* Ensure dates are limited explicitly or implicitly */
recurRetrieval = defaultRecurringRetrieval(recurRetrieval, startDate, endDate);
if (debug) {
trace("getEvents for start=" + startDate + " end=" + endDate);
}
FilterBase fltr = filter;
if (!Util.isEmpty(calendars)) {
FilterBase colfltr = null;
for (final BwCalendar c : calendars) {
colfltr = FilterBase.addOrChild(colfltr, new BwCollectionFilter(null, c));
}
fltr = FilterBase.addAndChild(fltr, colfltr);
}
int desiredAccess = privRead;
if (freeBusy) {
// DORECUR - freebusy events must have enough info for expansion
desiredAccess = privReadFreeBusy;
}
final List<PropertyInfoIndex> properties = new ArrayList<>(2);
properties.add(PropertyInfoIndex.DTSTART);
properties.add(PropertyInfoIndex.UTC);
final List<SortTerm> sort = new ArrayList<>(1);
sort.add(new SortTerm(properties, true));
String start = null;
String end = null;
if (startDate != null) {
start = startDate.getDate();
}
if (endDate != null) {
end = endDate.getDate();
}
final SearchResult sr = // query
getIndexer(null).search(// query
null, false, fltr, sort, // defaultFilterContext
null, start, end, -1, delState, recurRetrieval);
final List<SearchResultEntry> sres = sr.getIndexer().getSearchResult(sr, 0, -1, desiredAccess);
final TreeSet<CoreEventInfo> ceis = new TreeSet<>();
for (final SearchResultEntry sre : sres) {
final Object o = sre.getEntity();
if (!(o instanceof EventInfo)) {
continue;
}
final EventInfo ei = (EventInfo) o;
final BwEvent ev = ei.getEvent();
restoreCategories(ev);
final CoreEventInfo cei = postGetEvent(ev, null, ei.getCurrentAccess());
if (cei == null) {
continue;
}
ceis.add(cei);
}
return buildVavail(ceis);
}
use of org.bedework.calfacade.filter.SortTerm in project bw-calendar-engine by Bedework.
the class BwIndexEsImpl method search.
@Override
public SearchResult search(final String query, final boolean relevance, final FilterBase filter, final List<SortTerm> sort, final FilterBase defaultFilterContext, final String start, final String end, final int pageSize, final DeletedState deletedState, final RecurringRetrievalMode recurRetrieval) throws CalFacadeException {
if (basicSysprops.getTestMode()) {
final long timeSinceIndex = System.currentTimeMillis() - lastIndexTime;
final long waitTime = indexerDelay - timeSinceIndex;
if (waitTime > 0) {
try {
Thread.sleep(waitTime);
} catch (final InterruptedException ignored) {
}
}
}
final EsSearchResult res = new EsSearchResult(this);
res.start = start;
res.end = end;
res.pageSize = pageSize;
res.accessCheck = accessCheck;
res.delState = deletedState;
res.recurRetrieval = recurRetrieval;
if (query != null) {
final MatchQueryBuilder mqb = QueryBuilders.matchQuery("_all", query);
if (!relevance) {
mqb.operator(Operator.AND);
} else {
mqb.fuzziness("1");
mqb.prefixLength(2);
}
res.curQuery = mqb;
// res.curQuery = QueryBuilders.queryString(query);
}
final ESQueryFilter ef = getFilters(recurRetrieval);
res.curFilter = ef.buildFilter(filter);
if (res.curFilter instanceof MatchNone) {
res.setFound(0);
return res;
}
res.curFilter = ef.addDateRangeFilter(res.curFilter, IcalDefs.entityTypeEvent, start, end);
res.curFilter = ef.addLimits(res.curFilter, defaultFilterContext, res.delState);
if (res.curFilter instanceof MatchNone) {
res.setFound(0);
return res;
}
res.requiresSecondaryFetch = ef.requiresSecondaryFetch();
// res.canPage = ef.canPage();
res.curSort = sort;
final SearchRequestBuilder srb = getClient().prepareSearch(searchIndexes);
if (res.curQuery != null) {
srb.setQuery(res.curQuery);
}
srb.setSearchType(SearchType.COUNT).setPostFilter(res.curFilter).setFrom(0).setSize(0);
if (!Util.isEmpty(res.curSort)) {
SortOrder so;
for (final SortTerm st : res.curSort) {
if (st.isAscending()) {
so = SortOrder.ASC;
} else {
so = SortOrder.DESC;
}
srb.addSort(new FieldSortBuilder(ESQueryFilter.makePropertyRef(st.getProperties())).order(so));
}
}
res.latestStart = ef.getLatestStart();
res.earliestEnd = ef.getEarliestEnd();
if (debug) {
debug("Search: latestStart=" + res.latestStart + " earliestEnd=" + res.earliestEnd + " targetIndex=" + targetIndex + "; srb=" + srb);
}
final SearchResponse resp = srb.execute().actionGet();
if (debug) {
debug("Search: returned status " + resp.status() + " found: " + resp.getHits().getTotalHits());
}
res.setFound(resp.getHits().getTotalHits());
return res;
}
use of org.bedework.calfacade.filter.SortTerm in project bw-calendar-engine by Bedework.
the class BwIndexEsImpl method getSearchResult.
@Override
public List<SearchResultEntry> getSearchResult(final SearchResult sres, final int offset, final int num, final int desiredAccess) throws CalFacadeException {
if (debug) {
debug("offset: " + offset + ", num: " + num);
}
final EsSearchResult res = (EsSearchResult) sres;
res.pageStart = offset;
final SearchRequestBuilder srb = getClient().prepareSearch(searchIndexes);
if (res.curQuery != null) {
srb.setQuery(res.curQuery);
}
srb.setSearchType(SearchType.QUERY_THEN_FETCH).setPostFilter(res.curFilter).setFrom(res.pageStart);
final int size;
if (num < 0) {
size = (int) sres.getFound();
} else {
size = num;
}
// TODO - need a configurable absolute max size for fetches
srb.setSize(size);
final List<SearchResultEntry> entities = new ArrayList<>(size);
if (!Util.isEmpty(res.curSort)) {
SortOrder so;
for (final SortTerm st : res.curSort) {
if (st.isAscending()) {
so = SortOrder.ASC;
} else {
so = SortOrder.DESC;
}
srb.addSort(new FieldSortBuilder(ESQueryFilter.makePropertyRef(st.getProperties())).order(so));
}
}
if (res.requiresSecondaryFetch) {
// Limit to href then fetch those
srb.addField(ESQueryFilter.hrefJname);
}
final SearchResponse resp = srb.execute().actionGet();
if (resp.status() != RestStatus.OK) {
if (debug) {
debug("Search returned status " + resp.status());
}
}
final SearchHits hitsResp = resp.getHits();
if ((hitsResp.getHits() == null) || (hitsResp.getHits().length == 0)) {
return entities;
}
// Break condition: No hits are returned
if (hitsResp.hits().length == 0) {
return entities;
}
final List<SearchHit> hits;
if (res.requiresSecondaryFetch) {
hits = multiFetch(hitsResp, res.recurRetrieval);
if (hits == null) {
return entities;
}
} else {
hits = Arrays.asList(hitsResp.getHits());
}
final Map<String, Collection<BwEventAnnotation>> overrides = new HashMap<>();
final Collection<EventInfo> masters = new TreeSet<>();
EntityBuilder.checkFlushCache(currentChangeToken());
/* If we are retrieving events with a time range query and we are asking for the
* master + overrides then we need to check that the master really has an
* instance in the given time range */
final boolean checkTimeRange = (res.recurRetrieval.mode == Rmode.overrides) && ((res.latestStart != null) || (res.earliestEnd != null));
final Set<String> excluded = new TreeSet<>();
for (final SearchHit hit : hits) {
res.pageStart++;
final String dtype = hit.getType();
if (dtype == null) {
throw new CalFacadeException("org.bedework.index.noitemtype");
}
final String kval = hit.getId();
if (kval == null) {
throw new CalFacadeException("org.bedework.index.noitemkey");
}
final EntityBuilder eb = getEntityBuilder(hit.sourceAsMap());
Object entity = null;
switch(dtype) {
case docTypeCollection:
entity = eb.makeCollection();
break;
case docTypeCategory:
entity = eb.makeCat();
break;
case docTypeContact:
entity = eb.makeContact();
break;
case docTypeLocation:
entity = eb.makeLocation();
break;
case docTypeEvent:
case docTypePoll:
entity = eb.makeEvent(kval, res.recurRetrieval.mode == Rmode.expanded);
final EventInfo ei = (EventInfo) entity;
final BwEvent ev = ei.getEvent();
final Response evrestResp = new Response();
restoreEvProps(evrestResp, ei);
if (evrestResp.getStatus() != ok) {
warn("Failed restore of ev props: " + evrestResp);
}
final Acl.CurrentAccess ca = res.accessCheck.checkAccess(ev, desiredAccess, true);
if ((ca == null) || !ca.getAccessAllowed()) {
continue;
}
ei.setCurrentAccess(ca);
if (ev instanceof BwEventAnnotation) {
if (excluded.contains(ev.getUid())) {
continue;
}
// Treat as override
final Collection<BwEventAnnotation> ov = overrides.computeIfAbsent(ev.getHref(), k -> new TreeSet<>());
ov.add((BwEventAnnotation) ev);
continue;
}
if (checkTimeRange && dtype.equals(docTypeEvent) && ev.getRecurring()) {
if (Util.isEmpty(RecurUtil.getPeriods(ev, 99, 1, res.latestStart, res.earliestEnd).instances)) {
excluded.add(ev.getUid());
continue;
}
}
masters.add(ei);
break;
}
entities.add(new SearchResultEntry(entity, dtype, hit.getScore()));
}
for (final EventInfo ei : masters) {
final BwEvent ev = ei.getEvent();
if (ev.getRecurring()) {
final Collection<BwEventAnnotation> ov = overrides.get(ev.getHref());
if (ov != null) {
for (final BwEventAnnotation ann : ov) {
final BwEvent proxy = new BwEventProxy(ann);
ann.setTarget(ev);
ann.setMaster(ev);
final EventInfo oei = new EventInfo(proxy);
ei.addOverride(oei);
}
}
}
}
return entities;
}
Aggregations