Search in sources :

Example 1 with AllGroupHeadsCollector

use of org.apache.lucene.search.grouping.AllGroupHeadsCollector in project lucene-solr by apache.

the class SimpleFacets method computeDocSet.

protected DocSet computeDocSet(DocSet baseDocSet, List<String> excludeTagList) throws SyntaxError, IOException {
    Map<?, ?> tagMap = (Map<?, ?>) req.getContext().get("tags");
    // rb can be null if facets are being calculated from a RequestHandler e.g. MoreLikeThisHandler
    if (tagMap == null || rb == null) {
        return baseDocSet;
    }
    IdentityHashMap<Query, Boolean> excludeSet = new IdentityHashMap<>();
    for (String excludeTag : excludeTagList) {
        Object olst = tagMap.get(excludeTag);
        // tagMap has entries of List<String,List<QParser>>, but subject to change in the future
        if (!(olst instanceof Collection))
            continue;
        for (Object o : (Collection<?>) olst) {
            if (!(o instanceof QParser))
                continue;
            QParser qp = (QParser) o;
            excludeSet.put(qp.getQuery(), Boolean.TRUE);
        }
    }
    if (excludeSet.size() == 0)
        return baseDocSet;
    List<Query> qlist = new ArrayList<>();
    // add the base query
    if (!excludeSet.containsKey(rb.getQuery())) {
        qlist.add(rb.getQuery());
    }
    // add the filters
    if (rb.getFilters() != null) {
        for (Query q : rb.getFilters()) {
            if (!excludeSet.containsKey(q)) {
                qlist.add(q);
            }
        }
    }
    // get the new base docset for this facet
    DocSet base = searcher.getDocSet(qlist);
    if (rb.grouping() && rb.getGroupingSpec().isTruncateGroups()) {
        Grouping grouping = new Grouping(searcher, null, rb.getQueryCommand(), false, 0, false);
        grouping.setWithinGroupSort(rb.getGroupingSpec().getSortWithinGroup());
        if (rb.getGroupingSpec().getFields().length > 0) {
            grouping.addFieldCommand(rb.getGroupingSpec().getFields()[0], req);
        } else if (rb.getGroupingSpec().getFunctions().length > 0) {
            grouping.addFunctionCommand(rb.getGroupingSpec().getFunctions()[0], req);
        } else {
            return base;
        }
        AllGroupHeadsCollector allGroupHeadsCollector = grouping.getCommands().get(0).createAllGroupCollector();
        searcher.search(base.getTopFilter(), allGroupHeadsCollector);
        return new BitDocSet(allGroupHeadsCollector.retrieveGroupHeads(searcher.maxDoc()));
    } else {
        return base;
    }
}
Also used : Query(org.apache.lucene.search.Query) BooleanQuery(org.apache.lucene.search.BooleanQuery) IdentityHashMap(java.util.IdentityHashMap) ArrayList(java.util.ArrayList) Grouping(org.apache.solr.search.Grouping) AllGroupHeadsCollector(org.apache.lucene.search.grouping.AllGroupHeadsCollector) BitDocSet(org.apache.solr.search.BitDocSet) QParser(org.apache.solr.search.QParser) Collection(java.util.Collection) SimpleOrderedMap(org.apache.solr.common.util.SimpleOrderedMap) Map(java.util.Map) IdentityHashMap(java.util.IdentityHashMap) HashMap(java.util.HashMap) HashDocSet(org.apache.solr.search.HashDocSet) DocSet(org.apache.solr.search.DocSet) SortedIntDocSet(org.apache.solr.search.SortedIntDocSet) BitDocSet(org.apache.solr.search.BitDocSet)

Example 2 with AllGroupHeadsCollector

use of org.apache.lucene.search.grouping.AllGroupHeadsCollector in project lucene-solr by apache.

the class Grouping method execute.

public void execute() throws IOException {
    if (commands.isEmpty()) {
        throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "Specify at least one field, function or query to group by.");
    }
    DocListAndSet out = new DocListAndSet();
    qr.setDocListAndSet(out);
    SolrIndexSearcher.ProcessedFilter pf = searcher.getProcessedFilter(cmd.getFilter(), cmd.getFilterList());
    final Filter luceneFilter = pf.filter;
    maxDoc = searcher.maxDoc();
    needScores = (cmd.getFlags() & SolrIndexSearcher.GET_SCORES) != 0;
    boolean cacheScores = false;
    // NOTE: Change this when withinGroupSort can be specified per group
    if (!needScores && !commands.isEmpty()) {
        Sort withinGroupSort = commands.get(0).withinGroupSort;
        cacheScores = withinGroupSort == null || withinGroupSort.needsScores();
    } else if (needScores) {
        cacheScores = needScores;
    }
    getDocSet = (cmd.getFlags() & SolrIndexSearcher.GET_DOCSET) != 0;
    getDocList = (cmd.getFlags() & SolrIndexSearcher.GET_DOCLIST) != 0;
    query = QueryUtils.makeQueryable(cmd.getQuery());
    for (Command cmd : commands) {
        cmd.prepare();
    }
    AllGroupHeadsCollector<?> allGroupHeadsCollector = null;
    List<Collector> collectors = new ArrayList<>(commands.size());
    for (Command cmd : commands) {
        Collector collector = cmd.createFirstPassCollector();
        if (collector != null) {
            collectors.add(collector);
        }
        if (getGroupedDocSet && allGroupHeadsCollector == null) {
            collectors.add(allGroupHeadsCollector = cmd.createAllGroupCollector());
        }
    }
    DocSetCollector setCollector = null;
    if (getDocSet && allGroupHeadsCollector == null) {
        setCollector = new DocSetCollector(maxDoc);
        collectors.add(setCollector);
    }
    Collector allCollectors = MultiCollector.wrap(collectors);
    CachingCollector cachedCollector = null;
    if (cacheSecondPassSearch && allCollectors != null) {
        int maxDocsToCache = (int) Math.round(maxDoc * (maxDocsPercentageToCache / 100.0d));
        // Maybe we should have a minimum and a maximum, that defines the window we would like caching for.
        if (maxDocsToCache > 0) {
            allCollectors = cachedCollector = CachingCollector.create(allCollectors, cacheScores, maxDocsToCache);
        }
    }
    if (pf.postFilter != null) {
        pf.postFilter.setLastDelegate(allCollectors);
        allCollectors = pf.postFilter;
    }
    if (allCollectors != null) {
        searchWithTimeLimiter(luceneFilter, allCollectors);
        if (allCollectors instanceof DelegatingCollector) {
            ((DelegatingCollector) allCollectors).finish();
        }
    }
    if (getGroupedDocSet && allGroupHeadsCollector != null) {
        qr.setDocSet(new BitDocSet(allGroupHeadsCollector.retrieveGroupHeads(maxDoc)));
    } else if (getDocSet) {
        qr.setDocSet(setCollector.getDocSet());
    }
    collectors.clear();
    for (Command cmd : commands) {
        Collector collector = cmd.createSecondPassCollector();
        if (collector != null)
            collectors.add(collector);
    }
    if (!collectors.isEmpty()) {
        Collector secondPhaseCollectors = MultiCollector.wrap(collectors.toArray(new Collector[collectors.size()]));
        if (collectors.size() > 0) {
            if (cachedCollector != null) {
                if (cachedCollector.isCached()) {
                    cachedCollector.replay(secondPhaseCollectors);
                } else {
                    signalCacheWarning = true;
                    logger.warn(String.format(Locale.ROOT, "The grouping cache is active, but not used because it exceeded the max cache limit of %d percent", maxDocsPercentageToCache));
                    logger.warn("Please increase cache size or disable group caching.");
                    searchWithTimeLimiter(luceneFilter, secondPhaseCollectors);
                }
            } else {
                if (pf.postFilter != null) {
                    pf.postFilter.setLastDelegate(secondPhaseCollectors);
                    secondPhaseCollectors = pf.postFilter;
                }
                searchWithTimeLimiter(luceneFilter, secondPhaseCollectors);
            }
            if (secondPhaseCollectors instanceof DelegatingCollector) {
                ((DelegatingCollector) secondPhaseCollectors).finish();
            }
        }
    }
    for (Command cmd : commands) {
        cmd.finish();
    }
    qr.groupedResults = grouped;
    if (getDocList) {
        int sz = idSet.size();
        int[] ids = new int[sz];
        int idx = 0;
        for (int val : idSet) {
            ids[idx++] = val;
        }
        qr.setDocList(new DocSlice(0, sz, ids, null, maxMatches, maxScore));
    }
}
Also used : ArrayList(java.util.ArrayList) FirstPassGroupingCollector(org.apache.lucene.search.grouping.FirstPassGroupingCollector) AllGroupHeadsCollector(org.apache.lucene.search.grouping.AllGroupHeadsCollector) TotalHitCountCollector(org.apache.lucene.search.TotalHitCountCollector) TopGroupsCollector(org.apache.lucene.search.grouping.TopGroupsCollector) TopFieldCollector(org.apache.lucene.search.TopFieldCollector) AllGroupsCollector(org.apache.lucene.search.grouping.AllGroupsCollector) TimeLimitingCollector(org.apache.lucene.search.TimeLimitingCollector) FilterCollector(org.apache.solr.search.grouping.collector.FilterCollector) MultiCollector(org.apache.lucene.search.MultiCollector) Collector(org.apache.lucene.search.Collector) TopScoreDocCollector(org.apache.lucene.search.TopScoreDocCollector) CachingCollector(org.apache.lucene.search.CachingCollector) TopDocsCollector(org.apache.lucene.search.TopDocsCollector) Sort(org.apache.lucene.search.Sort) CachingCollector(org.apache.lucene.search.CachingCollector) SolrException(org.apache.solr.common.SolrException)

Example 3 with AllGroupHeadsCollector

use of org.apache.lucene.search.grouping.AllGroupHeadsCollector in project lucene-solr by apache.

the class CommandHandler method computeGroupedDocSet.

private DocSet computeGroupedDocSet(Query query, ProcessedFilter filter, List<Collector> collectors) throws IOException {
    Command firstCommand = commands.get(0);
    String field = firstCommand.getKey();
    SchemaField sf = searcher.getSchema().getField(field);
    FieldType fieldType = sf.getType();
    final AllGroupHeadsCollector allGroupHeadsCollector;
    if (fieldType.getNumberType() != null) {
        ValueSource vs = fieldType.getValueSource(sf, null);
        allGroupHeadsCollector = AllGroupHeadsCollector.newCollector(new ValueSourceGroupSelector(vs, new HashMap<>()), firstCommand.getWithinGroupSort());
    } else {
        allGroupHeadsCollector = AllGroupHeadsCollector.newCollector(new TermGroupSelector(firstCommand.getKey()), firstCommand.getWithinGroupSort());
    }
    if (collectors.isEmpty()) {
        searchWithTimeLimiter(query, filter, allGroupHeadsCollector);
    } else {
        collectors.add(allGroupHeadsCollector);
        searchWithTimeLimiter(query, filter, MultiCollector.wrap(collectors.toArray(new Collector[collectors.size()])));
    }
    return new BitDocSet(allGroupHeadsCollector.retrieveGroupHeads(searcher.maxDoc()));
}
Also used : SchemaField(org.apache.solr.schema.SchemaField) BitDocSet(org.apache.solr.search.BitDocSet) QueryCommand(org.apache.solr.search.QueryCommand) ValueSource(org.apache.lucene.queries.function.ValueSource) ValueSourceGroupSelector(org.apache.lucene.search.grouping.ValueSourceGroupSelector) TermGroupSelector(org.apache.lucene.search.grouping.TermGroupSelector) AllGroupHeadsCollector(org.apache.lucene.search.grouping.AllGroupHeadsCollector) FieldType(org.apache.solr.schema.FieldType)

Aggregations

AllGroupHeadsCollector (org.apache.lucene.search.grouping.AllGroupHeadsCollector)3 ArrayList (java.util.ArrayList)2 BitDocSet (org.apache.solr.search.BitDocSet)2 Collection (java.util.Collection)1 HashMap (java.util.HashMap)1 IdentityHashMap (java.util.IdentityHashMap)1 Map (java.util.Map)1 ValueSource (org.apache.lucene.queries.function.ValueSource)1 BooleanQuery (org.apache.lucene.search.BooleanQuery)1 CachingCollector (org.apache.lucene.search.CachingCollector)1 Collector (org.apache.lucene.search.Collector)1 MultiCollector (org.apache.lucene.search.MultiCollector)1 Query (org.apache.lucene.search.Query)1 Sort (org.apache.lucene.search.Sort)1 TimeLimitingCollector (org.apache.lucene.search.TimeLimitingCollector)1 TopDocsCollector (org.apache.lucene.search.TopDocsCollector)1 TopFieldCollector (org.apache.lucene.search.TopFieldCollector)1 TopScoreDocCollector (org.apache.lucene.search.TopScoreDocCollector)1 TotalHitCountCollector (org.apache.lucene.search.TotalHitCountCollector)1 AllGroupsCollector (org.apache.lucene.search.grouping.AllGroupsCollector)1