Package org.apache.solr.spelling

Source Code of org.apache.solr.spelling.PossibilityIterator

package org.apache.solr.spelling;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License.  You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.PriorityQueue;

import org.apache.lucene.analysis.Token;

/**
* <p>
* Given a list of possible Spelling Corrections for multiple mis-spelled words
* in a query, This iterator returns Possible Correction combinations ordered by
* reasonable probability that such a combination will return actual hits if
* re-queried. This implementation simply ranks the Possible Combinations by the
* sum of their component ranks.
* </p>
*
*/
public class PossibilityIterator implements Iterator<RankedSpellPossibility> {
  private List<List<SpellCheckCorrection>> possibilityList = new ArrayList<List<SpellCheckCorrection>>();
  private Iterator<RankedSpellPossibility> rankedPossibilityIterator = null;
  private int correctionIndex[];
  private boolean done = false;

  @SuppressWarnings("unused")
  private PossibilityIterator() {
    throw new AssertionError("You shan't go here.");
  }

  /**
   * <p>
   * We assume here that the passed-in inner LinkedHashMaps are already sorted
   * in order of "Best Possible Correction".
   * </p>
   *
   * @param suggestions
   */
  public PossibilityIterator(Map<Token, LinkedHashMap<String, Integer>> suggestions, int maximumRequiredSuggestions, int maxEvaluations) {
    for (Map.Entry<Token, LinkedHashMap<String, Integer>> entry : suggestions.entrySet()) {
      Token token = entry.getKey();
      List<SpellCheckCorrection> possibleCorrections = new ArrayList<SpellCheckCorrection>();
      for (Map.Entry<String, Integer> entry1 : entry.getValue().entrySet()) {
        SpellCheckCorrection correction = new SpellCheckCorrection();
        correction.setOriginal(token);
        correction.setCorrection(entry1.getKey());
        correction.setNumberOfOccurences(entry1.getValue());
        possibleCorrections.add(correction);
      }
      possibilityList.add(possibleCorrections);
    }

    int wrapSize = possibilityList.size();
    if (wrapSize == 0) {
      done = true;
    } else {
      correctionIndex = new int[wrapSize];
      for (int i = 0; i < wrapSize; i++) {
        int suggestSize = possibilityList.get(i).size();
        if (suggestSize == 0) {
          done = true;
          break;
        }
        correctionIndex[i] = 0;
      }
    }
   
    long count = 0;
    PriorityQueue<RankedSpellPossibility> rankedPossibilities = new PriorityQueue<RankedSpellPossibility>();   
    while (count < maxEvaluations && internalHasNext()) {
      RankedSpellPossibility rsp = internalNext();
      count++;     
     
      if(rankedPossibilities.size() >= maximumRequiredSuggestions && rsp.getRank() >= rankedPossibilities.peek().getRank()) {
        continue;
      }
      rankedPossibilities.offer(rsp);
      if(rankedPossibilities.size() > maximumRequiredSuggestions) {
        rankedPossibilities.poll();
      }
    }
   
    RankedSpellPossibility[] rpArr = new RankedSpellPossibility[rankedPossibilities.size()];
    for(int i=rankedPossibilities.size() - ; i>=0 ; i--) {
      rpArr[i] = rankedPossibilities.remove();
    }
    rankedPossibilityIterator = Arrays.asList(rpArr).iterator();   
  }

  private boolean internalHasNext() {
    return !done;
  }

  /**
   * <p>
   * This method is converting the independent LinkHashMaps containing various
   * (silo'ed) suggestions for each mis-spelled word into individual
   * "holistic query corrections", aka. "Spell Check Possibility"
   * </p>
   * <p>
   * Rank here is the sum of each selected term's position in its respective
   * LinkedHashMap.
   * </p>
   *
   * @return
   */
  private RankedSpellPossibility internalNext() {
    if (done) {
      throw new NoSuchElementException();
    }

    List<SpellCheckCorrection> possibleCorrection = new ArrayList<SpellCheckCorrection>();
    int rank = 0;
    for (int i = 0; i < correctionIndex.length; i++) {
      List<SpellCheckCorrection> singleWordPossibilities = possibilityList.get(i);
      SpellCheckCorrection singleWordPossibility = singleWordPossibilities.get(correctionIndex[i]);
      rank += correctionIndex[i];

      if (i == correctionIndex.length - 1) {
        correctionIndex[i]++;
        if (correctionIndex[i] == singleWordPossibilities.size()) {
          correctionIndex[i] = 0;
          if (correctionIndex.length == 1) {
            done = true;
          }
          for (int ii = i - 1; ii >= 0; ii--) {
            correctionIndex[ii]++;
            if (correctionIndex[ii] >= possibilityList.get(ii).size() && ii > 0) {
              correctionIndex[ii] = 0;
            } else {
              break;
            }
          }
        }
      }
      possibleCorrection.add(singleWordPossibility);
    }
   
    if(correctionIndex[0] == possibilityList.get(0).size())
    {
      done = true;
    }

    RankedSpellPossibility rsl = new RankedSpellPossibility();
    rsl.setCorrections(possibleCorrection);
    rsl.setRank(rank);
    return rsl;
  }

  public boolean hasNext() {
    return rankedPossibilityIterator.hasNext();
  }

  public RankedSpellPossibility next() {
    return rankedPossibilityIterator.next();
  }

  public void remove() {
    throw new UnsupportedOperationException();
  }

}
TOP

Related Classes of org.apache.solr.spelling.PossibilityIterator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.