Search in sources :

Example 11 with SearchComponent

use of org.apache.solr.handler.component.SearchComponent in project lucene-solr by apache.

the class SpellCheckCollator method collate.

public List<SpellCheckCollation> collate(SpellingResult result, String originalQuery, ResponseBuilder ultimateResponse) {
    List<SpellCheckCollation> collations = new ArrayList<>();
    QueryComponent queryComponent = null;
    if (ultimateResponse.components != null) {
        for (SearchComponent sc : ultimateResponse.components) {
            if (sc instanceof QueryComponent) {
                queryComponent = (QueryComponent) sc;
                break;
            }
        }
    }
    boolean verifyCandidateWithQuery = true;
    int maxTries = maxCollationTries;
    int maxNumberToIterate = maxTries;
    if (maxTries < 1) {
        maxTries = 1;
        maxNumberToIterate = maxCollations;
        verifyCandidateWithQuery = false;
    }
    if (queryComponent == null && verifyCandidateWithQuery) {
        LOG.info("Could not find an instance of QueryComponent.  Disabling collation verification against the index.");
        maxTries = 1;
        verifyCandidateWithQuery = false;
    }
    docCollectionLimit = docCollectionLimit > 0 ? docCollectionLimit : 0;
    int maxDocId = -1;
    if (verifyCandidateWithQuery && docCollectionLimit > 0) {
        IndexReader reader = ultimateResponse.req.getSearcher().getIndexReader();
        maxDocId = reader.maxDoc();
    }
    int tryNo = 0;
    int collNo = 0;
    PossibilityIterator possibilityIter = new PossibilityIterator(result.getSuggestions(), maxNumberToIterate, maxCollationEvaluations, suggestionsMayOverlap);
    while (tryNo < maxTries && collNo < maxCollations && possibilityIter.hasNext()) {
        PossibilityIterator.RankedSpellPossibility possibility = possibilityIter.next();
        String collationQueryStr = getCollation(originalQuery, possibility.corrections);
        int hits = 0;
        if (verifyCandidateWithQuery) {
            tryNo++;
            SolrParams origParams = ultimateResponse.req.getParams();
            ModifiableSolrParams params = new ModifiableSolrParams(origParams);
            Iterator<String> origParamIterator = origParams.getParameterNamesIterator();
            int pl = SpellingParams.SPELLCHECK_COLLATE_PARAM_OVERRIDE.length();
            while (origParamIterator.hasNext()) {
                String origParamName = origParamIterator.next();
                if (origParamName.startsWith(SpellingParams.SPELLCHECK_COLLATE_PARAM_OVERRIDE) && origParamName.length() > pl) {
                    String[] val = origParams.getParams(origParamName);
                    if (val.length == 1 && val[0].length() == 0) {
                        params.set(origParamName.substring(pl), (String[]) null);
                    } else {
                        params.set(origParamName.substring(pl), val);
                    }
                }
            }
            params.set(CommonParams.Q, collationQueryStr);
            params.remove(CommonParams.START);
            params.set(CommonParams.ROWS, "" + docCollectionLimit);
            // we don't want any stored fields
            params.set(CommonParams.FL, ID);
            // we'll sort by doc id to ensure no scoring is done.
            params.set(CommonParams.SORT, "_docid_ asc");
            // CursorMark does not like _docid_ sorting, and we don't need it.
            params.remove(CursorMarkParams.CURSOR_MARK_PARAM);
            // If a dismax query, don't add unnecessary clauses for scoring
            params.remove(DisMaxParams.TIE);
            params.remove(DisMaxParams.PF);
            params.remove(DisMaxParams.PF2);
            params.remove(DisMaxParams.PF3);
            params.remove(DisMaxParams.BQ);
            params.remove(DisMaxParams.BF);
            // Collate testing does not support Grouping (see SOLR-2577)
            params.remove(GroupParams.GROUP);
            // Collate testing does not support the Collapse QParser (See SOLR-8807)
            params.remove("expand");
            String[] filters = params.getParams(CommonParams.FQ);
            if (filters != null) {
                List<String> filtersToApply = new ArrayList<>(filters.length);
                for (String fq : filters) {
                    if (!fq.startsWith("{!collapse")) {
                        filtersToApply.add(fq);
                    }
                }
                params.set("fq", filtersToApply.toArray(new String[filtersToApply.size()]));
            }
            // creating a request here... make sure to close it!
            ResponseBuilder checkResponse = new ResponseBuilder(new LocalSolrQueryRequest(ultimateResponse.req.getCore(), params), new SolrQueryResponse(), Arrays.<SearchComponent>asList(queryComponent));
            checkResponse.setQparser(ultimateResponse.getQparser());
            checkResponse.setFilters(ultimateResponse.getFilters());
            checkResponse.setQueryString(collationQueryStr);
            checkResponse.components = Arrays.<SearchComponent>asList(queryComponent);
            try {
                queryComponent.prepare(checkResponse);
                if (docCollectionLimit > 0) {
                    int f = checkResponse.getFieldFlags();
                    checkResponse.setFieldFlags(f |= SolrIndexSearcher.TERMINATE_EARLY);
                }
                queryComponent.process(checkResponse);
                hits = (Integer) checkResponse.rsp.getToLog().get("hits");
            } catch (EarlyTerminatingCollectorException etce) {
                assert (docCollectionLimit > 0);
                assert 0 < etce.getNumberScanned();
                assert 0 < etce.getNumberCollected();
                if (etce.getNumberScanned() == maxDocId) {
                    hits = etce.getNumberCollected();
                } else {
                    hits = (int) (((float) (maxDocId * etce.getNumberCollected())) / (float) etce.getNumberScanned());
                }
            } catch (Exception e) {
                LOG.warn("Exception trying to re-query to check if a spell check possibility would return any hits.", e);
            } finally {
                checkResponse.req.close();
            }
        }
        if (hits > 0 || !verifyCandidateWithQuery) {
            collNo++;
            SpellCheckCollation collation = new SpellCheckCollation();
            collation.setCollationQuery(collationQueryStr);
            collation.setHits(hits);
            collation.setInternalRank(suggestionsMayOverlap ? ((possibility.rank * 1000) + possibility.index) : possibility.rank);
            NamedList<String> misspellingsAndCorrections = new NamedList<>();
            for (SpellCheckCorrection corr : possibility.corrections) {
                misspellingsAndCorrections.add(corr.getOriginal().toString(), corr.getCorrection());
            }
            collation.setMisspellingsAndCorrections(misspellingsAndCorrections);
            collations.add(collation);
        }
        if (LOG.isDebugEnabled()) {
            LOG.debug("Collation: " + collationQueryStr + (verifyCandidateWithQuery ? (" will return " + hits + " hits.") : ""));
        }
    }
    return collations;
}
Also used : QueryComponent(org.apache.solr.handler.component.QueryComponent) SolrQueryResponse(org.apache.solr.response.SolrQueryResponse) NamedList(org.apache.solr.common.util.NamedList) EarlyTerminatingCollectorException(org.apache.solr.search.EarlyTerminatingCollectorException) ArrayList(java.util.ArrayList) ModifiableSolrParams(org.apache.solr.common.params.ModifiableSolrParams) EarlyTerminatingCollectorException(org.apache.solr.search.EarlyTerminatingCollectorException) LocalSolrQueryRequest(org.apache.solr.request.LocalSolrQueryRequest) SearchComponent(org.apache.solr.handler.component.SearchComponent) IndexReader(org.apache.lucene.index.IndexReader) SolrParams(org.apache.solr.common.params.SolrParams) ModifiableSolrParams(org.apache.solr.common.params.ModifiableSolrParams) ResponseBuilder(org.apache.solr.handler.component.ResponseBuilder)

Example 12 with SearchComponent

use of org.apache.solr.handler.component.SearchComponent in project SearchServices by Alfresco.

the class AlfrescoSpellCheckCollator method collate.

public List<AlfrescoSpellCheckCollation> collate(SpellingResult result, String originalQuery, ResponseBuilder ultimateResponse) {
    List<AlfrescoSpellCheckCollation> collations = new ArrayList<>();
    QueryComponent queryComponent = null;
    if (ultimateResponse.components != null) {
        for (SearchComponent sc : ultimateResponse.components) {
            if (sc instanceof QueryComponent) {
                queryComponent = (QueryComponent) sc;
                break;
            }
        }
    }
    boolean verifyCandidateWithQuery = true;
    int maxTries = maxCollationTries;
    int maxNumberToIterate = maxTries;
    if (maxTries < 1) {
        maxTries = 1;
        maxNumberToIterate = maxCollations;
        verifyCandidateWithQuery = false;
    }
    if (queryComponent == null && verifyCandidateWithQuery) {
        LOG.info("Could not find an instance of QueryComponent. Disabling collation verification against the index.");
        maxTries = 1;
        verifyCandidateWithQuery = false;
    }
    docCollectionLimit = docCollectionLimit > 0 ? docCollectionLimit : 0;
    int maxDocId = -1;
    if (verifyCandidateWithQuery && docCollectionLimit > 0) {
        IndexReader reader = ultimateResponse.req.getSearcher().getIndexReader();
        maxDocId = reader.maxDoc();
    }
    JSONObject alfrescoJSON = (JSONObject) ultimateResponse.req.getContext().get(AbstractQParser.ALFRESCO_JSON);
    String originalAftsQuery = alfrescoJSON != null ? alfrescoJSON.getString("query") : ultimateResponse.getQueryString();
    int tryNo = 0;
    int collNo = 0;
    PossibilityIterator possibilityIter = new PossibilityIterator(result.getSuggestions(), maxNumberToIterate, maxCollationEvaluations, suggestionsMayOverlap);
    while (tryNo < maxTries && collNo < maxCollations && possibilityIter.hasNext()) {
        PossibilityIterator.RankedSpellPossibility possibility = possibilityIter.next();
        String collationQueryStr = getCollation(originalQuery, possibility.corrections);
        int hits = 0;
        String aftsQuery = null;
        if (verifyCandidateWithQuery) {
            tryNo++;
            SolrQueryRequest req = ultimateResponse.req;
            SolrParams origParams = req.getParams();
            ModifiableSolrParams params = new ModifiableSolrParams(origParams);
            Iterator<String> origParamIterator = origParams.getParameterNamesIterator();
            int pl = SpellingParams.SPELLCHECK_COLLATE_PARAM_OVERRIDE.length();
            while (origParamIterator.hasNext()) {
                String origParamName = origParamIterator.next();
                if (origParamName.startsWith(SpellingParams.SPELLCHECK_COLLATE_PARAM_OVERRIDE) && origParamName.length() > pl) {
                    String[] val = origParams.getParams(origParamName);
                    if (val.length == 1 && val[0].length() == 0) {
                        params.set(origParamName.substring(pl), (String[]) null);
                    } else {
                        params.set(origParamName.substring(pl), val);
                    }
                }
            }
            // we don't set the 'q' param, as we'll pass the query via JSON.
            // params.set(CommonParams.Q, collationQueryStr);
            params.remove(CommonParams.START);
            params.set(CommonParams.ROWS, "" + docCollectionLimit);
            // we don't want any stored fields
            params.set(CommonParams.FL, "id");
            // we'll sort by doc id to ensure no scoring is done.
            params.set(CommonParams.SORT, "_docid_ asc");
            // If a dismax query, don't add unnecessary clauses for scoring
            params.remove(DisMaxParams.TIE);
            params.remove(DisMaxParams.PF);
            params.remove(DisMaxParams.PF2);
            params.remove(DisMaxParams.PF3);
            params.remove(DisMaxParams.BQ);
            params.remove(DisMaxParams.BF);
            // Collate testing does not support Grouping (see SOLR-2577)
            params.remove(GroupParams.GROUP);
            boolean useQStr = true;
            if (alfrescoJSON != null) {
                try {
                    aftsQuery = originalAftsQuery.replaceAll(Pattern.quote(originalQuery), Matcher.quoteReplacement(collationQueryStr));
                    alfrescoJSON.put("query", aftsQuery);
                    req.getContext().put(AbstractQParser.ALFRESCO_JSON, alfrescoJSON);
                    useQStr = false;
                } catch (JSONException e) {
                    LOG.warn("Exception trying to get/set the query from/to ALFRESCO_JSON.]" + e);
                }
            } else {
                aftsQuery = collationQueryStr;
            }
            req.setParams(params);
            // creating a request here... make sure to close it!
            ResponseBuilder checkResponse = new ResponseBuilder(req, new SolrQueryResponse(), Arrays.<SearchComponent>asList(queryComponent));
            checkResponse.setQparser(ultimateResponse.getQparser());
            checkResponse.setFilters(ultimateResponse.getFilters());
            checkResponse.components = Arrays.<SearchComponent>asList(queryComponent);
            if (useQStr) {
                checkResponse.setQueryString(collationQueryStr);
            }
            try {
                queryComponent.prepare(checkResponse);
                if (docCollectionLimit > 0) {
                    int f = checkResponse.getFieldFlags();
                    checkResponse.setFieldFlags(f |= SolrIndexSearcher.TERMINATE_EARLY);
                }
                queryComponent.process(checkResponse);
                hits = (Integer) checkResponse.rsp.getToLog().get("hits");
            } catch (EarlyTerminatingCollectorException etce) {
                assert (docCollectionLimit > 0);
                assert 0 < etce.getNumberScanned();
                assert 0 < etce.getNumberCollected();
                if (etce.getNumberScanned() == maxDocId) {
                    hits = etce.getNumberCollected();
                } else {
                    hits = (int) (((float) (maxDocId * etce.getNumberCollected())) / (float) etce.getNumberScanned());
                }
            } catch (Exception e) {
                LOG.warn("Exception trying to re-query to check if a spell check possibility would return any hits." + e);
            } finally {
                checkResponse.req.close();
            }
        }
        if (hits > 0 || !verifyCandidateWithQuery) {
            collNo++;
            AlfrescoSpellCheckCollation collation = new AlfrescoSpellCheckCollation();
            collation.setCollationQuery(aftsQuery);
            collation.setCollationQueryString(collationQueryStr);
            collation.setHits(hits);
            collation.setInternalRank(suggestionsMayOverlap ? ((possibility.rank * 1000) + possibility.index) : possibility.rank);
            NamedList<String> misspellingsAndCorrections = new NamedList<>();
            for (SpellCheckCorrection corr : possibility.corrections) {
                misspellingsAndCorrections.add(corr.getOriginal().toString(), corr.getCorrection());
            }
            collation.setMisspellingsAndCorrections(misspellingsAndCorrections);
            collations.add(collation);
        }
        if (LOG.isDebugEnabled()) {
            LOG.debug("Collation: " + aftsQuery + (verifyCandidateWithQuery ? (" will return " + hits + " hits.") : ""));
        }
    }
    return collations;
}
Also used : QueryComponent(org.apache.solr.handler.component.QueryComponent) ArrayList(java.util.ArrayList) PossibilityIterator(org.apache.solr.spelling.PossibilityIterator) ModifiableSolrParams(org.apache.solr.common.params.ModifiableSolrParams) ResponseBuilder(org.apache.solr.handler.component.ResponseBuilder) SolrQueryResponse(org.apache.solr.response.SolrQueryResponse) SpellCheckCorrection(org.apache.solr.spelling.SpellCheckCorrection) NamedList(org.apache.solr.common.util.NamedList) EarlyTerminatingCollectorException(org.apache.solr.search.EarlyTerminatingCollectorException) JSONException(org.json.JSONException) JSONException(org.json.JSONException) EarlyTerminatingCollectorException(org.apache.solr.search.EarlyTerminatingCollectorException) SolrQueryRequest(org.apache.solr.request.SolrQueryRequest) JSONObject(org.json.JSONObject) SearchComponent(org.apache.solr.handler.component.SearchComponent) IndexReader(org.apache.lucene.index.IndexReader) SolrParams(org.apache.solr.common.params.SolrParams) ModifiableSolrParams(org.apache.solr.common.params.ModifiableSolrParams)

Aggregations

SearchComponent (org.apache.solr.handler.component.SearchComponent)12 SolrQueryResponse (org.apache.solr.response.SolrQueryResponse)12 ModifiableSolrParams (org.apache.solr.common.params.ModifiableSolrParams)11 LocalSolrQueryRequest (org.apache.solr.request.LocalSolrQueryRequest)11 SolrQueryRequest (org.apache.solr.request.SolrQueryRequest)11 NamedList (org.apache.solr.common.util.NamedList)10 Test (org.junit.Test)10 SolrCore (org.apache.solr.core.SolrCore)9 SolrRequestHandler (org.apache.solr.request.SolrRequestHandler)9 SimpleOrderedMap (org.apache.solr.common.util.SimpleOrderedMap)8 List (java.util.List)4 ResponseBuilder (org.apache.solr.handler.component.ResponseBuilder)3 ArrayList (java.util.ArrayList)2 IndexReader (org.apache.lucene.index.IndexReader)2 SolrParams (org.apache.solr.common.params.SolrParams)2 QueryComponent (org.apache.solr.handler.component.QueryComponent)2 EarlyTerminatingCollectorException (org.apache.solr.search.EarlyTerminatingCollectorException)2 HashSet (java.util.HashSet)1 Term (org.apache.lucene.index.Term)1 SpanPayloadCheckQuery (org.apache.lucene.queries.payloads.SpanPayloadCheckQuery)1