Search in sources :

Example 1 with SortTerm

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);
}
Also used : SortTerm(org.bedework.calfacade.filter.SortTerm) CoreEventInfo(org.bedework.calcorei.CoreEventInfo) EventInfo(org.bedework.calfacade.svc.EventInfo) CoreEventInfo(org.bedework.calcorei.CoreEventInfo) ArrayList(java.util.ArrayList) SearchResult(org.bedework.calfacade.indexing.SearchResult) BwEvent(org.bedework.calfacade.BwEvent) BwCalendar(org.bedework.calfacade.BwCalendar) BwCollectionFilter(org.bedework.calfacade.filter.BwCollectionFilter) PropertyInfoIndex(org.bedework.util.calendar.PropertyIndex.PropertyInfoIndex) TreeSet(java.util.TreeSet) FilterBase(org.bedework.caldav.util.filter.FilterBase) SearchResultEntry(org.bedework.calfacade.indexing.SearchResultEntry)

Example 2 with SortTerm

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;
}
Also used : SortTerm(org.bedework.calfacade.filter.SortTerm) SearchRequestBuilder(org.elasticsearch.action.search.SearchRequestBuilder) MatchQueryBuilder(org.elasticsearch.index.query.MatchQueryBuilder) SortOrder(org.elasticsearch.search.sort.SortOrder) FieldSortBuilder(org.elasticsearch.search.sort.FieldSortBuilder) SearchResponse(org.elasticsearch.action.search.SearchResponse)

Example 3 with SortTerm

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;
}
Also used : SearchHit(org.elasticsearch.search.SearchHit) EventInfo(org.bedework.calfacade.svc.EventInfo) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) BwEvent(org.bedework.calfacade.BwEvent) BwEventProxy(org.bedework.calfacade.BwEventProxy) TreeSet(java.util.TreeSet) SearchHits(org.elasticsearch.search.SearchHits) SortTerm(org.bedework.calfacade.filter.SortTerm) SearchRequestBuilder(org.elasticsearch.action.search.SearchRequestBuilder) SortOrder(org.elasticsearch.search.sort.SortOrder) FieldSortBuilder(org.elasticsearch.search.sort.FieldSortBuilder) Acl(org.bedework.access.Acl) CalFacadeException(org.bedework.calfacade.exc.CalFacadeException) SearchResponse(org.elasticsearch.action.search.SearchResponse) GetAliasesResponse(org.elasticsearch.action.admin.indices.alias.get.GetAliasesResponse) UpdateResponse(org.elasticsearch.action.update.UpdateResponse) BulkResponse(org.elasticsearch.action.bulk.BulkResponse) CreateIndexResponse(org.elasticsearch.action.admin.indices.create.CreateIndexResponse) Response(org.bedework.calfacade.responses.Response) IndicesAliasesResponse(org.elasticsearch.action.admin.indices.alias.IndicesAliasesResponse) GetEntityResponse(org.bedework.calfacade.responses.GetEntityResponse) IndicesStatusResponse(org.elasticsearch.action.admin.indices.status.IndicesStatusResponse) DeleteByQueryResponse(org.elasticsearch.action.deletebyquery.DeleteByQueryResponse) DeleteIndexResponse(org.elasticsearch.action.admin.indices.delete.DeleteIndexResponse) IndexDeleteByQueryResponse(org.elasticsearch.action.deletebyquery.IndexDeleteByQueryResponse) ReindexResponse(org.bedework.calfacade.indexing.ReindexResponse) GetResponse(org.elasticsearch.action.get.GetResponse) SearchResponse(org.elasticsearch.action.search.SearchResponse) IndexStatsResponse(org.bedework.calfacade.indexing.IndexStatsResponse) IndexResponse(org.elasticsearch.action.index.IndexResponse) ClusterHealthResponse(org.elasticsearch.action.admin.cluster.health.ClusterHealthResponse) BwEventAnnotation(org.bedework.calfacade.BwEventAnnotation) Collection(java.util.Collection) SearchResultEntry(org.bedework.calfacade.indexing.SearchResultEntry)

Aggregations

SortTerm (org.bedework.calfacade.filter.SortTerm)3 ArrayList (java.util.ArrayList)2 TreeSet (java.util.TreeSet)2 BwEvent (org.bedework.calfacade.BwEvent)2 SearchResultEntry (org.bedework.calfacade.indexing.SearchResultEntry)2 EventInfo (org.bedework.calfacade.svc.EventInfo)2 SearchRequestBuilder (org.elasticsearch.action.search.SearchRequestBuilder)2 SearchResponse (org.elasticsearch.action.search.SearchResponse)2 FieldSortBuilder (org.elasticsearch.search.sort.FieldSortBuilder)2 SortOrder (org.elasticsearch.search.sort.SortOrder)2 Collection (java.util.Collection)1 HashMap (java.util.HashMap)1 Acl (org.bedework.access.Acl)1 CoreEventInfo (org.bedework.calcorei.CoreEventInfo)1 FilterBase (org.bedework.caldav.util.filter.FilterBase)1 BwCalendar (org.bedework.calfacade.BwCalendar)1 BwEventAnnotation (org.bedework.calfacade.BwEventAnnotation)1 BwEventProxy (org.bedework.calfacade.BwEventProxy)1 CalFacadeException (org.bedework.calfacade.exc.CalFacadeException)1 BwCollectionFilter (org.bedework.calfacade.filter.BwCollectionFilter)1