Puneet Sharma created SOLR-18311:
------------------------------------

             Summary: SpellCheckCollator/PossibilityIterator: 
spellcheck.maxCollationEvaluations truncation produces incomplete/order-biased 
top-N collations instead of true lowest-rank combinations
                 Key: SOLR-18311
                 URL: https://issues.apache.org/jira/browse/SOLR-18311
             Project: Solr
          Issue Type: Bug
          Components: spellchecker
    Affects Versions: 9.6.1
            Reporter: Puneet Sharma


{{PossibilityIterator}} generates every candidate collation for a multi-word 
misspelled query as the Cartesian product of each word's per-token suggestion 
list, then keeps only the best {{N}} ({{{}maxCollationTries{}}}, or 
{{maxCollations}} when tries is unset) ranked by "sum of chosen suggestion 
indices" (lower = better), via a bounded max-heap ({{{}PriorityQueue{}}} in 
{{{}PossibilityIterator(...){}}}, 
solr/core/src/java/org/apache/solr/spelling/PossibilityIterator.java:93-133).

The candidates are generated by a mixed-radix "odometer" 
({{{}internalNextAdvance(){}}}, PossibilityIterator.java:187-238): the _last_ 
misspelled word's suggestion index increments fastest, carrying into earlier 
words only on wraparound. This means combinations are visited in lexicographic 
index order, *not* in increasing rank order — rank is provably non-monotonic 
across the visitation sequence (see repro below).

Enumeration is capped by {{spellcheck.maxCollationEvaluations}} (default 10000; 
consumed at 
solr/core/src/java/org/apache/solr/handler/component/SpellCheckComponent.java:307,
 and enforced by the {{numEvaluations < maxEvaluations}} loop condition at 
PossibilityIterator.java:100).

Because the odometer is not rank-ordered, this cap has two effects, one a pure 
inefficiency and one an actual correctness gap:
 # *Wasted work when the full product fits under the cap.* All combinations get 
scored even though only the top {{maxCollationTries}} (e.g. the commonly-used 
value 10) are ever kept. E.g. a 6-misspelled-word query with 5 suggestions/word 
already generates 5^6 = 15,625 combinations, of which only 10 survive — 15,615 
evaluations (and, for {{verifyCandidateWithQuery=true}} cases downstream in 
{{{}SpellCheckCollator.collate(){}}}, up to {{maxCollationTries}} {_}actual 
re-queries against the index{_}) are pure overhead that a rank-ordered 
generator would avoid entirely.

 # *Incomplete / order-biased results once the product exceeds the cap.* Since 
the outer (first) misspelled word's index only advances after its _entire_ 
inner block is exhausted, hitting {{maxCollationEvaluations}} mid-walk means 
later index values of the first misspelled word are _never visited at all_ — 
regardless of how low their rank would have been. The resulting "top N" 
therefore silently depends on which word happens to be enumerated first (i.e. 
token position order in the suggestions map), not on true rank quality. This 
means {{spellcheck.collate}} can return worse suggestions — or fail to find a 
valid collation at all — than the data actually supports, purely as an artifact 
of enumeration order, with no way for a caller to detect that this happened (no 
partial-results flag, no log line at INFO level).



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to