Search in sources :

Example 1 with SolrSpellChecker

use of org.apache.solr.spelling.SolrSpellChecker in project lucene-solr by apache.

the class SpellCheckComponent method process.

@Override
@SuppressWarnings("unchecked")
public void process(ResponseBuilder rb) throws IOException {
    SolrParams params = rb.req.getParams();
    if (!params.getBool(COMPONENT_NAME, false) || spellCheckers.isEmpty()) {
        return;
    }
    boolean shardRequest = "true".equals(params.get(ShardParams.IS_SHARD));
    String q = params.get(SPELLCHECK_Q);
    SolrSpellChecker spellChecker = getSpellChecker(params);
    Collection<Token> tokens = null;
    if (q != null) {
        //we have a spell check param, tokenize it with the query analyzer applicable for this spellchecker
        tokens = getTokens(q, spellChecker.getQueryAnalyzer());
    } else {
        q = rb.getQueryString();
        if (q == null) {
            q = params.get(CommonParams.Q);
        }
        tokens = queryConverter.convert(q);
    }
    if (tokens != null && tokens.isEmpty() == false) {
        if (spellChecker != null) {
            int count = params.getInt(SPELLCHECK_COUNT, 1);
            boolean onlyMorePopular = params.getBool(SPELLCHECK_ONLY_MORE_POPULAR, DEFAULT_ONLY_MORE_POPULAR);
            boolean extendedResults = params.getBool(SPELLCHECK_EXTENDED_RESULTS, false);
            boolean collate = params.getBool(SPELLCHECK_COLLATE, false);
            float accuracy = params.getFloat(SPELLCHECK_ACCURACY, Float.MIN_VALUE);
            int alternativeTermCount = params.getInt(SpellingParams.SPELLCHECK_ALTERNATIVE_TERM_COUNT, 0);
            //If specified, this can be a discrete # of results, or a percentage of fq results.
            Integer maxResultsForSuggest = maxResultsForSuggest(rb);
            ModifiableSolrParams customParams = new ModifiableSolrParams();
            for (String checkerName : getDictionaryNames(params)) {
                customParams.add(getCustomParams(checkerName, params));
            }
            Integer hitsInteger = (Integer) rb.rsp.getToLog().get("hits");
            long hits = 0;
            if (hitsInteger == null) {
                hits = rb.getNumberDocumentsFound();
            } else {
                hits = hitsInteger.longValue();
            }
            SpellingResult spellingResult = null;
            if (maxResultsForSuggest == null || hits <= maxResultsForSuggest) {
                SuggestMode suggestMode = SuggestMode.SUGGEST_WHEN_NOT_IN_INDEX;
                if (onlyMorePopular) {
                    suggestMode = SuggestMode.SUGGEST_MORE_POPULAR;
                } else if (alternativeTermCount > 0) {
                    suggestMode = SuggestMode.SUGGEST_ALWAYS;
                }
                IndexReader reader = rb.req.getSearcher().getIndexReader();
                SpellingOptions options = new SpellingOptions(tokens, reader, count, alternativeTermCount, suggestMode, extendedResults, accuracy, customParams);
                spellingResult = spellChecker.getSuggestions(options);
            } else {
                spellingResult = new SpellingResult();
            }
            boolean isCorrectlySpelled = hits > (maxResultsForSuggest == null ? 0 : maxResultsForSuggest);
            NamedList response = new SimpleOrderedMap();
            NamedList suggestions = toNamedList(shardRequest, spellingResult, q, extendedResults);
            response.add("suggestions", suggestions);
            if (extendedResults) {
                response.add("correctlySpelled", isCorrectlySpelled);
            }
            if (collate) {
                addCollationsToResponse(params, spellingResult, rb, q, response, spellChecker.isSuggestionsMayOverlap());
            }
            if (shardRequest) {
                addOriginalTermsToResponse(response, tokens);
            }
            rb.rsp.add("spellcheck", response);
        } else {
            throw new SolrException(SolrException.ErrorCode.NOT_FOUND, "Specified dictionaries do not exist: " + getDictionaryNameAsSingleString(getDictionaryNames(params)));
        }
    }
}
Also used : ConjunctionSolrSpellChecker(org.apache.solr.spelling.ConjunctionSolrSpellChecker) SolrSpellChecker(org.apache.solr.spelling.SolrSpellChecker) NamedList(org.apache.solr.common.util.NamedList) Token(org.apache.lucene.analysis.Token) SpellingOptions(org.apache.solr.spelling.SpellingOptions) SimpleOrderedMap(org.apache.solr.common.util.SimpleOrderedMap) ModifiableSolrParams(org.apache.solr.common.params.ModifiableSolrParams) SuggestMode(org.apache.lucene.search.spell.SuggestMode) SpellingResult(org.apache.solr.spelling.SpellingResult) IndexReader(org.apache.lucene.index.IndexReader) SolrParams(org.apache.solr.common.params.SolrParams) ModifiableSolrParams(org.apache.solr.common.params.ModifiableSolrParams) SolrException(org.apache.solr.common.SolrException)

Example 2 with SolrSpellChecker

use of org.apache.solr.spelling.SolrSpellChecker in project lucene-solr by apache.

the class SpellCheckComponent method getSpellChecker.

protected SolrSpellChecker getSpellChecker(SolrParams params) {
    String[] dictName = getDictionaryNames(params);
    if (dictName.length == 1) {
        return spellCheckers.get(dictName[0]);
    } else {
        String singleStr = getDictionaryNameAsSingleString(dictName);
        SolrSpellChecker ssc = spellCheckers.get(singleStr);
        if (ssc == null) {
            ConjunctionSolrSpellChecker cssc = new ConjunctionSolrSpellChecker();
            for (String dn : dictName) {
                cssc.addChecker(spellCheckers.get(dn));
            }
            ssc = cssc;
        }
        return ssc;
    }
}
Also used : ConjunctionSolrSpellChecker(org.apache.solr.spelling.ConjunctionSolrSpellChecker) ConjunctionSolrSpellChecker(org.apache.solr.spelling.ConjunctionSolrSpellChecker) SolrSpellChecker(org.apache.solr.spelling.SolrSpellChecker)

Example 3 with SolrSpellChecker

use of org.apache.solr.spelling.SolrSpellChecker in project lucene-solr by apache.

the class SpellCheckComponent method addSpellChecker.

private boolean addSpellChecker(SolrCore core, boolean hasDefault, NamedList spellchecker) {
    String className = (String) spellchecker.get("classname");
    if (className == null)
        className = (String) spellchecker.get("class");
    // so that it's mandatory in a future release?
    if (className == null)
        className = IndexBasedSpellChecker.class.getName();
    SolrResourceLoader loader = core.getResourceLoader();
    SolrSpellChecker checker = loader.newInstance(className, SolrSpellChecker.class);
    if (checker != null) {
        String dictionary = checker.init(spellchecker, core);
        if (dictionary != null) {
            boolean isDefault = dictionary.equals(SolrSpellChecker.DEFAULT_DICTIONARY_NAME);
            if (isDefault && !hasDefault) {
                hasDefault = true;
            } else if (isDefault && hasDefault) {
                throw new RuntimeException("More than one dictionary is missing name.");
            }
            spellCheckers.put(dictionary, checker);
        } else {
            if (!hasDefault) {
                spellCheckers.put(SolrSpellChecker.DEFAULT_DICTIONARY_NAME, checker);
                hasDefault = true;
            } else {
                throw new RuntimeException("More than one dictionary is missing name.");
            }
        }
        // Register event listeners for this SpellChecker
        core.registerFirstSearcherListener(new SpellCheckerListener(core, checker, false, false));
        boolean buildOnCommit = Boolean.parseBoolean((String) spellchecker.get("buildOnCommit"));
        boolean buildOnOptimize = Boolean.parseBoolean((String) spellchecker.get("buildOnOptimize"));
        if (buildOnCommit || buildOnOptimize) {
            LOG.info("Registering newSearcher listener for spellchecker: " + checker.getDictionaryName());
            core.registerNewSearcherListener(new SpellCheckerListener(core, checker, buildOnCommit, buildOnOptimize));
        }
    } else {
        throw new RuntimeException("Can't load spell checker: " + className);
    }
    return hasDefault;
}
Also used : SolrResourceLoader(org.apache.solr.core.SolrResourceLoader) ConjunctionSolrSpellChecker(org.apache.solr.spelling.ConjunctionSolrSpellChecker) SolrSpellChecker(org.apache.solr.spelling.SolrSpellChecker)

Example 4 with SolrSpellChecker

use of org.apache.solr.spelling.SolrSpellChecker in project lucene-solr by apache.

the class SpellCheckComponent method finishStage.

@Override
@SuppressWarnings({ "unchecked", "deprecation" })
public void finishStage(ResponseBuilder rb) {
    SolrParams params = rb.req.getParams();
    if (!params.getBool(COMPONENT_NAME, false) || rb.stage != ResponseBuilder.STAGE_GET_FIELDS)
        return;
    boolean extendedResults = params.getBool(SPELLCHECK_EXTENDED_RESULTS, false);
    boolean collate = params.getBool(SPELLCHECK_COLLATE, false);
    boolean collationExtendedResults = params.getBool(SPELLCHECK_COLLATE_EXTENDED_RESULTS, false);
    int maxCollationTries = params.getInt(SPELLCHECK_MAX_COLLATION_TRIES, 0);
    int maxCollations = params.getInt(SPELLCHECK_MAX_COLLATIONS, 1);
    Integer maxResultsForSuggest = maxResultsForSuggest(rb);
    int count = rb.req.getParams().getInt(SPELLCHECK_COUNT, 1);
    int numSug = Math.max(count, AbstractLuceneSpellChecker.DEFAULT_SUGGESTION_COUNT);
    String origQuery = params.get(SPELLCHECK_Q);
    if (origQuery == null) {
        origQuery = rb.getQueryString();
        if (origQuery == null) {
            origQuery = params.get(CommonParams.Q);
        }
    }
    long hits = rb.grouping() ? rb.totalHitCount : rb.getNumberDocumentsFound();
    boolean isCorrectlySpelled = hits > (maxResultsForSuggest == null ? 0 : maxResultsForSuggest);
    SpellCheckMergeData mergeData = new SpellCheckMergeData();
    if (maxResultsForSuggest == null || !isCorrectlySpelled) {
        for (ShardRequest sreq : rb.finished) {
            for (ShardResponse srsp : sreq.responses) {
                NamedList nl = null;
                try {
                    nl = (NamedList) srsp.getSolrResponse().getResponse().get("spellcheck");
                } catch (Exception e) {
                    if (rb.req.getParams().getBool(ShardParams.SHARDS_TOLERANT, false)) {
                        // looks like a shard did not return anything
                        continue;
                    }
                    throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, "Unable to read spelling info for shard: " + srsp.getShard(), e);
                }
                LOG.info(srsp.getShard() + " " + nl);
                if (nl != null) {
                    mergeData.totalNumberShardResponses++;
                    collectShardSuggestions(nl, mergeData);
                    collectShardCollations(mergeData, nl, maxCollationTries);
                }
            }
        }
    }
    // all shard responses have been collected
    // create token and get top suggestions
    SolrSpellChecker checker = getSpellChecker(rb.req.getParams());
    SpellingResult result = checker.mergeSuggestions(mergeData, numSug, count, extendedResults);
    NamedList response = new SimpleOrderedMap();
    NamedList suggestions = toNamedList(false, result, origQuery, extendedResults);
    response.add("suggestions", suggestions);
    if (extendedResults) {
        response.add("correctlySpelled", isCorrectlySpelled);
    }
    if (collate) {
        SpellCheckCollation[] sortedCollations = mergeData.collations.values().toArray(new SpellCheckCollation[mergeData.collations.size()]);
        Arrays.sort(sortedCollations);
        NamedList collations = new NamedList();
        int i = 0;
        while (i < maxCollations && i < sortedCollations.length) {
            SpellCheckCollation collation = sortedCollations[i];
            i++;
            if (collationExtendedResults) {
                SimpleOrderedMap extendedResult = new SimpleOrderedMap();
                extendedResult.add("collationQuery", collation.getCollationQuery());
                extendedResult.add("hits", collation.getHits());
                extendedResult.add("misspellingsAndCorrections", collation.getMisspellingsAndCorrections());
                collations.add("collation", extendedResult);
            } else {
                collations.add("collation", collation.getCollationQuery());
            }
        }
        response.add("collations", collations);
    }
    rb.rsp.add("spellcheck", response);
}
Also used : ConjunctionSolrSpellChecker(org.apache.solr.spelling.ConjunctionSolrSpellChecker) SolrSpellChecker(org.apache.solr.spelling.SolrSpellChecker) NamedList(org.apache.solr.common.util.NamedList) SimpleOrderedMap(org.apache.solr.common.util.SimpleOrderedMap) SolrException(org.apache.solr.common.SolrException) IOException(java.io.IOException) SpellingResult(org.apache.solr.spelling.SpellingResult) SolrParams(org.apache.solr.common.params.SolrParams) ModifiableSolrParams(org.apache.solr.common.params.ModifiableSolrParams) SpellCheckCollation(org.apache.solr.spelling.SpellCheckCollation) SolrException(org.apache.solr.common.SolrException)

Example 5 with SolrSpellChecker

use of org.apache.solr.spelling.SolrSpellChecker in project lucene-solr by apache.

the class SpellCheckComponent method prepare.

@Override
@SuppressWarnings("unchecked")
public void prepare(ResponseBuilder rb) throws IOException {
    SolrParams params = rb.req.getParams();
    if (!params.getBool(COMPONENT_NAME, false)) {
        return;
    }
    SolrSpellChecker spellChecker = getSpellChecker(params);
    if (params.getBool(SPELLCHECK_BUILD, false)) {
        spellChecker.build(rb.req.getCore(), rb.req.getSearcher());
        rb.rsp.add("command", "build");
    } else if (params.getBool(SPELLCHECK_RELOAD, false)) {
        spellChecker.reload(rb.req.getCore(), rb.req.getSearcher());
        rb.rsp.add("command", "reload");
    }
}
Also used : ConjunctionSolrSpellChecker(org.apache.solr.spelling.ConjunctionSolrSpellChecker) SolrSpellChecker(org.apache.solr.spelling.SolrSpellChecker) SolrParams(org.apache.solr.common.params.SolrParams) ModifiableSolrParams(org.apache.solr.common.params.ModifiableSolrParams)

Aggregations

ConjunctionSolrSpellChecker (org.apache.solr.spelling.ConjunctionSolrSpellChecker)5 SolrSpellChecker (org.apache.solr.spelling.SolrSpellChecker)5 ModifiableSolrParams (org.apache.solr.common.params.ModifiableSolrParams)3 SolrParams (org.apache.solr.common.params.SolrParams)3 SolrException (org.apache.solr.common.SolrException)2 NamedList (org.apache.solr.common.util.NamedList)2 SimpleOrderedMap (org.apache.solr.common.util.SimpleOrderedMap)2 SpellingResult (org.apache.solr.spelling.SpellingResult)2 IOException (java.io.IOException)1 Token (org.apache.lucene.analysis.Token)1 IndexReader (org.apache.lucene.index.IndexReader)1 SuggestMode (org.apache.lucene.search.spell.SuggestMode)1 SolrResourceLoader (org.apache.solr.core.SolrResourceLoader)1 SpellCheckCollation (org.apache.solr.spelling.SpellCheckCollation)1 SpellingOptions (org.apache.solr.spelling.SpellingOptions)1