Search in sources :

Example 1 with LeafFieldComparator

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

the class FirstPassGroupingCollector method buildSortedSet.

private void buildSortedSet() throws IOException {
    final Comparator<CollectedSearchGroup<?>> comparator = new Comparator<CollectedSearchGroup<?>>() {

        @Override
        public int compare(CollectedSearchGroup<?> o1, CollectedSearchGroup<?> o2) {
            for (int compIDX = 0; ; compIDX++) {
                FieldComparator<?> fc = comparators[compIDX];
                final int c = reversed[compIDX] * fc.compare(o1.comparatorSlot, o2.comparatorSlot);
                if (c != 0) {
                    return c;
                } else if (compIDX == compIDXEnd) {
                    return o1.topDoc - o2.topDoc;
                }
            }
        }
    };
    orderedGroups = new TreeSet<>(comparator);
    orderedGroups.addAll(groupMap.values());
    assert orderedGroups.size() > 0;
    for (LeafFieldComparator fc : leafComparators) {
        fc.setBottom(orderedGroups.last().comparatorSlot);
    }
}
Also used : LeafFieldComparator(org.apache.lucene.search.LeafFieldComparator) LeafFieldComparator(org.apache.lucene.search.LeafFieldComparator) FieldComparator(org.apache.lucene.search.FieldComparator) Comparator(java.util.Comparator)

Example 2 with LeafFieldComparator

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

the class FirstPassGroupingCollector method collect.

@Override
public void collect(int doc) throws IOException {
    if (isCompetitive(doc) == false)
        return;
    // TODO: should we add option to mean "ignore docs that
    // don't have the group field" (instead of stuffing them
    // under null group)?
    groupSelector.advanceTo(doc);
    T groupValue = groupSelector.currentValue();
    final CollectedSearchGroup<T> group = groupMap.get(groupValue);
    if (group == null) {
        if (groupMap.size() < topNGroups) {
            // Still in startup transient: we have not
            // seen enough unique groups to start pruning them;
            // just keep collecting them
            // Add a new CollectedSearchGroup:
            CollectedSearchGroup<T> sg = new CollectedSearchGroup<>();
            sg.groupValue = groupSelector.copyValue();
            sg.comparatorSlot = groupMap.size();
            sg.topDoc = docBase + doc;
            for (LeafFieldComparator fc : leafComparators) {
                fc.copy(sg.comparatorSlot, doc);
            }
            groupMap.put(sg.groupValue, sg);
            if (groupMap.size() == topNGroups) {
                // End of startup transient: we now have max
                // number of groups; from here on we will drop
                // bottom group when we insert new one:
                buildSortedSet();
            }
            return;
        }
        // We already tested that the document is competitive, so replace
        // the bottom group with this new group.
        final CollectedSearchGroup<T> bottomGroup = orderedGroups.pollLast();
        assert orderedGroups.size() == topNGroups - 1;
        groupMap.remove(bottomGroup.groupValue);
        // reuse the removed CollectedSearchGroup
        bottomGroup.groupValue = groupSelector.copyValue();
        bottomGroup.topDoc = docBase + doc;
        for (LeafFieldComparator fc : leafComparators) {
            fc.copy(bottomGroup.comparatorSlot, doc);
        }
        groupMap.put(bottomGroup.groupValue, bottomGroup);
        orderedGroups.add(bottomGroup);
        assert orderedGroups.size() == topNGroups;
        final int lastComparatorSlot = orderedGroups.last().comparatorSlot;
        for (LeafFieldComparator fc : leafComparators) {
            fc.setBottom(lastComparatorSlot);
        }
        return;
    }
    // Update existing group:
    for (int compIDX = 0; ; compIDX++) {
        leafComparators[compIDX].copy(spareSlot, doc);
        final int c = reversed[compIDX] * comparators[compIDX].compare(group.comparatorSlot, spareSlot);
        if (c < 0) {
            // Definitely not competitive.
            return;
        } else if (c > 0) {
            // Definitely competitive; set remaining comparators:
            for (int compIDX2 = compIDX + 1; compIDX2 < comparators.length; compIDX2++) {
                leafComparators[compIDX2].copy(spareSlot, doc);
            }
            break;
        } else if (compIDX == compIDXEnd) {
            // this doc cannot compete with any other document in the queue.
            return;
        }
    }
    // Remove before updating the group since lookup is done via comparators
    // TODO: optimize this
    final CollectedSearchGroup<T> prevLast;
    if (orderedGroups != null) {
        prevLast = orderedGroups.last();
        orderedGroups.remove(group);
        assert orderedGroups.size() == topNGroups - 1;
    } else {
        prevLast = null;
    }
    group.topDoc = docBase + doc;
    // Swap slots
    final int tmp = spareSlot;
    spareSlot = group.comparatorSlot;
    group.comparatorSlot = tmp;
    // Re-add the changed group
    if (orderedGroups != null) {
        orderedGroups.add(group);
        assert orderedGroups.size() == topNGroups;
        final CollectedSearchGroup<?> newLast = orderedGroups.last();
        // If we changed the value of the last group, or changed which group was last, then update bottom:
        if (group == newLast || prevLast != newLast) {
            for (LeafFieldComparator fc : leafComparators) {
                fc.setBottom(newLast.comparatorSlot);
            }
        }
    }
}
Also used : LeafFieldComparator(org.apache.lucene.search.LeafFieldComparator)

Example 3 with LeafFieldComparator

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

the class BlockGroupingCollector method collect.

@Override
public void collect(int doc) throws IOException {
    if (doc > groupEndDocID) {
        // Group changed
        if (subDocUpto != 0) {
            processGroup();
        }
        groupEndDocID = lastDocPerGroupBits.advance(doc);
        //System.out.println("  adv " + groupEndDocID + " " + lastDocPerGroupBits);
        subDocUpto = 0;
        groupCompetes = !queueFull;
    }
    totalHitCount++;
    // Always cache doc/score within this group:
    if (subDocUpto == pendingSubDocs.length) {
        pendingSubDocs = ArrayUtil.grow(pendingSubDocs);
    }
    pendingSubDocs[subDocUpto] = doc;
    if (needsScores) {
        if (subDocUpto == pendingSubScores.length) {
            pendingSubScores = ArrayUtil.grow(pendingSubScores);
        }
        pendingSubScores[subDocUpto] = scorer.score();
    }
    subDocUpto++;
    if (groupCompetes) {
        if (subDocUpto == 1) {
            assert !queueFull;
            //System.out.println("    init copy to bottomSlot=" + bottomSlot);
            for (LeafFieldComparator fc : leafComparators) {
                fc.copy(bottomSlot, doc);
                fc.setBottom(bottomSlot);
            }
            topGroupDoc = doc;
        } else {
            // Compare to bottomSlot
            for (int compIDX = 0; ; compIDX++) {
                final int c = reversed[compIDX] * leafComparators[compIDX].compareBottom(doc);
                if (c < 0) {
                    // Definitely not competitive -- done
                    return;
                } else if (c > 0) {
                    // Definitely competitive.
                    break;
                } else if (compIDX == compIDXEnd) {
                    // order), so not competitive:
                    return;
                }
            }
            for (LeafFieldComparator fc : leafComparators) {
                fc.copy(bottomSlot, doc);
                // Necessary because some comparators cache
                // details of bottom slot; this forces them to
                // re-cache:
                fc.setBottom(bottomSlot);
            }
            topGroupDoc = doc;
        }
    } else {
        // queue yet
        for (int compIDX = 0; ; compIDX++) {
            final int c = reversed[compIDX] * leafComparators[compIDX].compareBottom(doc);
            if (c < 0) {
                //System.out.println("    doc doesn't compete w/ top groups");
                return;
            } else if (c > 0) {
                // Definitely competitive.
                break;
            } else if (compIDX == compIDXEnd) {
                //System.out.println("    doc doesn't compete w/ top groups");
                return;
            }
        }
        groupCompetes = true;
        for (LeafFieldComparator fc : leafComparators) {
            fc.copy(bottomSlot, doc);
            // Necessary because some comparators cache
            // details of bottom slot; this forces them to
            // re-cache:
            fc.setBottom(bottomSlot);
        }
        topGroupDoc = doc;
    //System.out.println("        doc competes w/ top groups");
    }
}
Also used : LeafFieldComparator(org.apache.lucene.search.LeafFieldComparator)

Example 4 with LeafFieldComparator

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

the class QueryComponent method doFieldSortValues.

protected void doFieldSortValues(ResponseBuilder rb, SolrIndexSearcher searcher) throws IOException {
    SolrQueryRequest req = rb.req;
    SolrQueryResponse rsp = rb.rsp;
    // The query cache doesn't currently store sort field values, and SolrIndexSearcher doesn't
    // currently have an option to return sort field values.  Because of this, we
    // take the documents given and re-derive the sort values.
    //
    // TODO: See SOLR-5595
    boolean fsv = req.getParams().getBool(ResponseBuilder.FIELD_SORT_VALUES, false);
    if (fsv) {
        // order is important for the sort fields
        NamedList<Object[]> sortVals = new NamedList<>();
        IndexReaderContext topReaderContext = searcher.getTopReaderContext();
        List<LeafReaderContext> leaves = topReaderContext.leaves();
        LeafReaderContext currentLeaf = null;
        if (leaves.size() == 1) {
            // if there is a single segment, use that subReader and avoid looking up each time
            currentLeaf = leaves.get(0);
            leaves = null;
        }
        DocList docList = rb.getResults().docList;
        // sort ids from lowest to highest so we can access them in order
        int nDocs = docList.size();
        final long[] sortedIds = new long[nDocs];
        // doc scores, parallel to sortedIds
        final float[] scores = new float[nDocs];
        DocList docs = rb.getResults().docList;
        DocIterator it = docs.iterator();
        for (int i = 0; i < nDocs; i++) {
            sortedIds[i] = (((long) it.nextDoc()) << 32) | i;
            scores[i] = docs.hasScores() ? it.score() : Float.NaN;
        }
        // sort ids and scores together
        new InPlaceMergeSorter() {

            @Override
            protected void swap(int i, int j) {
                long tmpId = sortedIds[i];
                float tmpScore = scores[i];
                sortedIds[i] = sortedIds[j];
                scores[i] = scores[j];
                sortedIds[j] = tmpId;
                scores[j] = tmpScore;
            }

            @Override
            protected int compare(int i, int j) {
                return Long.compare(sortedIds[i], sortedIds[j]);
            }
        }.sort(0, sortedIds.length);
        SortSpec sortSpec = rb.getSortSpec();
        Sort sort = searcher.weightSort(sortSpec.getSort());
        SortField[] sortFields = sort == null ? new SortField[] { SortField.FIELD_SCORE } : sort.getSort();
        List<SchemaField> schemaFields = sortSpec.getSchemaFields();
        for (int fld = 0; fld < schemaFields.size(); fld++) {
            SchemaField schemaField = schemaFields.get(fld);
            FieldType ft = null == schemaField ? null : schemaField.getType();
            SortField sortField = sortFields[fld];
            SortField.Type type = sortField.getType();
            // :TODO: would be simpler to always serialize every position of SortField[]
            if (type == SortField.Type.SCORE || type == SortField.Type.DOC)
                continue;
            FieldComparator<?> comparator = sortField.getComparator(1, 0);
            LeafFieldComparator leafComparator = null;
            Object[] vals = new Object[nDocs];
            int lastIdx = -1;
            int idx = 0;
            for (int i = 0; i < sortedIds.length; ++i) {
                long idAndPos = sortedIds[i];
                float score = scores[i];
                int doc = (int) (idAndPos >>> 32);
                int position = (int) idAndPos;
                if (leaves != null) {
                    idx = ReaderUtil.subIndex(doc, leaves);
                    currentLeaf = leaves.get(idx);
                    if (idx != lastIdx) {
                        // we switched segments.  invalidate leafComparator.
                        lastIdx = idx;
                        leafComparator = null;
                    }
                }
                if (leafComparator == null) {
                    leafComparator = comparator.getLeafComparator(currentLeaf);
                }
                // adjust for what segment this is in
                doc -= currentLeaf.docBase;
                leafComparator.setScorer(new FakeScorer(doc, score));
                leafComparator.copy(0, doc);
                Object val = comparator.value(0);
                if (null != ft)
                    val = ft.marshalSortValue(val);
                vals[position] = val;
            }
            sortVals.add(sortField.getField(), vals);
        }
        rsp.add("sort_values", sortVals);
    }
}
Also used : DocIterator(org.apache.solr.search.DocIterator) SortField(org.apache.lucene.search.SortField) LeafFieldComparator(org.apache.lucene.search.LeafFieldComparator) LeafReaderContext(org.apache.lucene.index.LeafReaderContext) Sort(org.apache.lucene.search.Sort) SolrQueryResponse(org.apache.solr.response.SolrQueryResponse) NamedList(org.apache.solr.common.util.NamedList) InPlaceMergeSorter(org.apache.lucene.util.InPlaceMergeSorter) IndexReaderContext(org.apache.lucene.index.IndexReaderContext) FieldType(org.apache.solr.schema.FieldType) SchemaField(org.apache.solr.schema.SchemaField) SolrQueryRequest(org.apache.solr.request.SolrQueryRequest) DocList(org.apache.solr.search.DocList) SortSpec(org.apache.solr.search.SortSpec)

Aggregations

LeafFieldComparator (org.apache.lucene.search.LeafFieldComparator)4 Comparator (java.util.Comparator)1 IndexReaderContext (org.apache.lucene.index.IndexReaderContext)1 LeafReaderContext (org.apache.lucene.index.LeafReaderContext)1 FieldComparator (org.apache.lucene.search.FieldComparator)1 Sort (org.apache.lucene.search.Sort)1 SortField (org.apache.lucene.search.SortField)1 InPlaceMergeSorter (org.apache.lucene.util.InPlaceMergeSorter)1 NamedList (org.apache.solr.common.util.NamedList)1 SolrQueryRequest (org.apache.solr.request.SolrQueryRequest)1 SolrQueryResponse (org.apache.solr.response.SolrQueryResponse)1 FieldType (org.apache.solr.schema.FieldType)1 SchemaField (org.apache.solr.schema.SchemaField)1 DocIterator (org.apache.solr.search.DocIterator)1 DocList (org.apache.solr.search.DocList)1 SortSpec (org.apache.solr.search.SortSpec)1