private AbstractIterator getIterator()

in oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrQueryIndex.java [258:418]


    private AbstractIterator<SolrResultRow> getIterator(final Filter filter, final IndexPlan plan,
                                                        final String parent, final int parentDepth,
                                                        final OakSolrConfiguration configuration, final SolrClient solrServer,
                                                        final LMSEstimator estimator) {
        return new AbstractIterator<SolrResultRow>() {
            public Collection<FacetField> facetFields = new LinkedList<FacetField>();
            private final Set<String> seenPaths = Sets.newHashSet();
            private final Deque<SolrResultRow> queue = Queues.newArrayDeque();
            private int offset = 0;
            private boolean noDocs = false;
            private long numFound = 0;

            @Override
            protected SolrResultRow computeNext() {
                if (!queue.isEmpty() || loadDocs()) {
                    return queue.remove();
                }
                return endOfData();
            }

            private SolrResultRow convertToRow(SolrDocument doc) {
                String path = String.valueOf(doc.getFieldValue(configuration.getPathField()));
                if ("".equals(path)) {
                    path = "/";
                }
                if (!parent.isEmpty()) {
                    path = getAncestorPath(path, parentDepth);
                    // avoid duplicate entries
                    if (seenPaths.contains(path)) {
                        return null;
                    }
                    seenPaths.add(path);
                }

                float score = 0f;
                Object scoreObj = doc.get("score");
                if (scoreObj != null) {
                    score = (Float) scoreObj;
                }
                return new SolrResultRow(path, score, doc, facetFields);

            }

            /**
             * Loads the Solr documents in batches
             * @return true if any document is loaded
             */
            private boolean loadDocs() {

                if (noDocs) {
                    return false;
                }

                try {
                    if (log.isDebugEnabled()) {
                        log.debug("converting filter {}", filter);
                    }
                    SolrQuery query = FilterQueryParser.getQuery(filter, plan, configuration);
                    if (numFound > 0) {
                        long rows = configuration.getRows();
                        long maxQueries = numFound / 2;
                        if (maxQueries > configuration.getRows()) {
                            // adjust the rows to avoid making more than 3 Solr requests for this particular query
                            rows = maxQueries;
                            query.setParam("rows", String.valueOf(rows));
                        }
                        long newOffset = configuration.getRows() + offset * rows;
                        if (newOffset >= numFound) {
                            return false;
                        }
                        query.setParam("start", String.valueOf(newOffset));
                        offset++;
                    }
                    if (log.isDebugEnabled()) {
                        log.debug("sending query {}", query);
                    }
                    QueryResponse queryResponse = solrServer.query(query);

                    if (log.isDebugEnabled()) {
                        log.debug("getting response {}", queryResponse.getHeader());
                    }

                    SolrDocumentList docs = queryResponse.getResults();

                    if (docs != null) {

                        numFound = docs.getNumFound();

                        estimator.update(filter, numFound);

                        Map<String, Map<String, List<String>>> highlighting = queryResponse.getHighlighting();
                        for (SolrDocument doc : docs) {
                            // handle highlight
                            if (highlighting != null) {
                                Object pathObject = doc.getFieldValue(configuration.getPathField());
                                if (pathObject != null && highlighting.get(String.valueOf(pathObject)) != null) {
                                    Map<String, List<String>> value = highlighting.get(String.valueOf(pathObject));
                                    for (Map.Entry<String, List<String>> entry : value.entrySet()) {
                                        // all highlighted values end up in 'rep:excerpt', regardless of field match
                                        for (String v : entry.getValue()) {
                                            doc.addField(QueryConstants.REP_EXCERPT, v);
                                        }
                                    }
                                }
                            }
                            SolrResultRow row = convertToRow(doc);
                            if (row != null) {
                                queue.add(row);
                            }
                        }
                    }

                    // get facets
                    List<FacetField> returnedFieldFacet = queryResponse.getFacetFields();
                    if (returnedFieldFacet != null) {
                        facetFields.addAll(returnedFieldFacet);
                    }

                    // filter facets on doc paths
                    if (!facetFields.isEmpty() && docs != null) {
                        for (SolrDocument doc : docs) {
                            String path = String.valueOf(doc.getFieldValue(configuration.getPathField()));
                            // if facet path doesn't exist for the calling user, filter the facet for this doc
                            for (FacetField ff : facetFields) {
                                if (!filter.isAccessible(path + "/" + ff.getName())) {
                                    filterFacet(doc, ff);
                                }
                            }
                        }
                    }

                    // handle spellcheck
                    SpellCheckResponse spellCheckResponse = queryResponse.getSpellCheckResponse();
                    if (spellCheckResponse != null && spellCheckResponse.getSuggestions() != null &&
                            spellCheckResponse.getSuggestions().size() > 0) {
                        putSpellChecks(spellCheckResponse, queue, filter, configuration, solrServer);
                        noDocs = true;
                    }

                    // handle suggest
                    NamedList<Object> response = queryResponse.getResponse();
                    Map suggest = (Map) response.get("suggest");
                    if (suggest != null) {
                        Set<Map.Entry<String, Object>> suggestEntries = suggest.entrySet();
                        if (!suggestEntries.isEmpty()) {
                            putSuggestions(suggestEntries, queue, filter, configuration, solrServer);
                            noDocs = true;
                        }
                    }

                } catch (Exception e) {
                    if (log.isWarnEnabled()) {
                        log.warn("query via {} failed.", solrServer, e);
                    }
                }

                return !queue.isEmpty();
            }

        };
    }