Interface AnnotationSearchRankingStrategy

All Known Implementing Classes:
CommonalityRankingStrategy, CompositeRankingStrategy, LuceneOrderRankingStrategy, TokenCoverageRankingStrategy, UsageWeightedRankingStrategy

public interface AnnotationSearchRankingStrategy
Strategy hook for re-ordering a flat list of annotation-search hits before they are wrapped in the response value-object and returned to the client.

Implementations get the original query string, the Lucene-ordered hits (original index = list position), and a per-URI usage-count map (number of distinct experiments that reference each URI). They must return a new list — same hits, possibly re-ordered — and must be stable and side-effect free. They must not mutate the input list.

See handoffs/RECCE_ANNOTATION_SEARCH_RANKING.md for the motivating design.

See Also:
  • Method Details

    • rank

      List<CharacteristicValueObject> rank(String originalQuery, List<CharacteristicValueObject> rawHits, Map<String,Integer> usageCountsByUri)
      Re-order rawHits according to this strategy.
      Parameters:
      originalQuery - the original query string the user typed; whitespace-tokenised and lowercased by token-coverage strategies; may be blank.
      rawHits - the Lucene-ordered hits; index in this list is the "original rank" used by rank-aware strategies. Must not be mutated.
      usageCountsByUri - per-URI count of distinct experiments referencing the URI; may be empty.
      Returns:
      a new list of the same hits in the desired display order.
    • rank

      default List<CharacteristicValueObject> rank(String originalQuery, List<CharacteristicValueObject> rawHits, Map<String,Integer> usageCountsByUri, Map<String,Integer> stringPriorByUri)
      Re-order rawHits with the per-string corpus prior available in addition to the usage counts.

      Callers should invoke this overload; it defaults to the three-argument rank(String, List, Map) so a strategy that has no use for the prior needs no changes. Only strategies that return true from requiresStringPrior() receive a populated map.

      Parameters:
      stringPriorByUri - per-URI count of distinct experiments on which a prior curator wrote the query string itself as the annotation's original value; may be empty. Distinct from usageCountsByUri, which counts every use of the URI regardless of what was written.
    • rank

      default List<CharacteristicValueObject> rank(String originalQuery, List<CharacteristicValueObject> rawHits, Map<String,Integer> usageCountsByUri, Map<String,Integer> stringPriorByUri, Map<String,String> matchedTextByUri)
      Re-order rawHits with the per-URI matched text available in addition to the counts.

      Callers should invoke this overload; it defaults to the four-argument rank(String, List, Map) so a strategy with no use for the matched text needs no changes.

      This exists because a coverage-scoring strategy that reads only hit.getValue() scores zero for a hit that matched through a synonym — its label shares nothing with the query, which is the entire reason the synonym exists. dmso finding dimethyl sulfoxide worked only by accident, both candidates scoring 0 coverage so usage broke the tie. The attribution pass already computes this string for the whole candidate set before truncation, so passing it costs nothing.

      Parameters:
      matchedTextByUri - per-URI text that actually matched the query — a preferred label, a declared synonym, or an alternate label — as reported by matchedText; may be empty, and may omit URIs whose attribution could not be resolved.
    • getName

      String getName()
      Short stable name used as the value of the ?rank= query parameter and as the bean name in the strategy registry. Lowercase, single word.
    • requiresUsageCounts

      default boolean requiresUsageCounts()
      Whether this strategy reads the usageCountsByUri map during rank(String, List, Map). Default false; strategies that do (usage, composite) override to true. When false, callers can skip the count lookup entirely for the candidate set and only compute counts for the truncated top-N display payload — turning the dominant cost on the typeahead path (~2-3s for a 400-1000 candidate IN-clause against the characteristic-by-uri index) into a much cheaper top-N query.
    • requiresStringPrior

      default boolean requiresStringPrior()
      Whether this strategy reads the stringPriorByUri map during rank(String, List, Map). Default false; CommonalityRankingStrategy overrides to true.

      Kept separate from requiresUsageCounts() rather than folded into one "needs corpus stats" flag because the two queries have different costs and answer different questions: a strategy that wants the per-string prior should not be made to pay for the usage scan, or the other way round.