aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Blott2015-05-16 13:18:07 +0100
committerStephen Blott2015-05-16 13:18:07 +0100
commitfdb41edfeb763cc4805e640ced7a576b7bebe02f (patch)
tree356e472a349c6d460165b9b55b52a95ef43800eb
parentea2795c37fe8fce95c6ed1e97ae503aac81ee45a (diff)
parent87c214ffd80ac436273f35fd95c800589e3f7d4a (diff)
downloadvimium-fdb41edfeb763cc4805e640ced7a576b7bebe02f.tar.bz2
Merge pull request #1663 from smblott-github/search-completion-with-regular-relevancy
Search completion with regular relevancy calculation
-rw-r--r--background_scripts/completion.coffee50
1 files changed, 32 insertions, 18 deletions
diff --git a/background_scripts/completion.coffee b/background_scripts/completion.coffee
index da858ca9..ee41aa07 100644
--- a/background_scripts/completion.coffee
+++ b/background_scripts/completion.coffee
@@ -156,6 +156,12 @@ class Suggestion
[ '.', [ "^https?://", "\\W+$" ].map (re) -> new RegExp re ]
]
+ # Boost a relevancy score by a factor (in the range (0,1.0)), while keeping the score in the range [0,1].
+ # This makes greater adjustments to scores near the middle of the range (so, very poor relevancy scores
+ # remain very poor).
+ @boostRelevancyScore: (factor, score) ->
+ score + if score < 0.5 then score * factor else (1.0 - score) * factor
+
class BookmarkCompleter
folderSeparator: "/"
currentSearch: null
@@ -449,18 +455,9 @@ class SearchEngineCompleter
factor = Math.max 0.0, Math.min 1.0, Settings.get "omniSearchWeight"
haveCompletionEngine = (0.0 < factor or custom) and CompletionSearch.haveCompletionEngine searchUrl
- # Relevancy:
- # - Relevancy does not depend upon the actual suggestion (so, it does not depend upon word
- # relevancy, say). We assume that the completion engine has already factored that in. Also,
- # completion engines sometimes handle spelling mistakes, in which case we wouldn't find the query
- # terms in the suggestion anyway.
- # - Scores are weighted such that they retain the order provided by the completion engine.
- # - The relavancy is higher if the query term is longer. The idea is that search suggestions are more
- # likely to be relevant if, after typing some number of characters, the user hasn't yet found
- # a useful suggestion from another completer.
- #
- characterCount = query.length - queryTerms.length + 1
- relevancy = (if custom then 0.5 else factor) * 12.0 / Math.max 12.0, characterCount
+ # We weight the relevancy factor by the length of the query (exponentially). The idea is that, the
+ # more the user has typed, the less likely it is that another completer has proven fruitful.
+ factor *= 1 - Math.pow 0.8, query.length
# This filter is applied to all of the suggestions from all of the completers, after they have been
# aggregated by the MultiCompleter.
@@ -488,15 +485,19 @@ class SearchEngineCompleter
forceAutoSelect: custom
highlightTerms: not haveCompletionEngine
- mkSuggestion = (suggestion) ->
+ mkSuggestion = (suggestion) =>
new Suggestion
queryTerms: queryTerms
type: description
url: Utils.createSearchUrl suggestion, searchUrl
title: suggestion
- relevancy: relevancy *= 0.9
insertText: suggestion
highlightTerms: false
+ isCustomSearch: custom
+ relevancyFunction: @computeRelevancy
+ # We reduce the relevancy factor as suggestions are added. This respects, to some extent, the
+ # order provided by the completion engine.
+ relevancyData: factor *= 0.95
cachedSuggestions =
if haveCompletionEngine then CompletionSearch.complete searchUrl, queryTerms else null
@@ -515,11 +516,16 @@ class SearchEngineCompleter
onComplete suggestions,
filter: filter
continuation: (suggestions, onComplete) =>
- # Fetch completion suggestions from suggestion engines.
- # We can skip this if any new suggestions we propose cannot score highly enough to make the list
- # anyway.
- if 10 <= suggestions.length and relevancy < suggestions[suggestions.length-1].relevancy
+ # We can skip querying the completion engine if any new suggestions we propose will not score highly
+ # enough to make the list anyway. We construct a suggestion which perfectly matches the query, and
+ # ask the relevancy function what score it would get. If that score is less than the score of the
+ # lowest-ranked suggestion from another completer (and there are already 10 suggestions), then
+ # there's no need to query the completion engine.
+ perfectRelevancyScore = @computeRelevancy new Suggestion
+ queryTerms: queryTerms, title: queryTerms.join(" "), relevancyData: factor
+
+ if 10 <= suggestions.length and perfectRelevancyScore < suggestions[suggestions.length-1].relevancy
console.log "skip (cannot make the grade):", suggestions.length, query if SearchEngineCompleter.debug
return onComplete []
@@ -527,6 +533,14 @@ class SearchEngineCompleter
console.log "fetched suggestions:", suggestions.length, query if SearchEngineCompleter.debug
onComplete suggestions.map mkSuggestion
+ computeRelevancy: ({ relevancyData, queryTerms, title }) ->
+ # Tweaks:
+ # - Calibration: we boost relevancy scores to try to achieve an appropriate balance between relevancy
+ # scores here, and those provided by other completers.
+ # - Relevancy depends only on the title (which is the search terms), and not on the URL.
+ Suggestion.boostRelevancyScore 0.5,
+ relevancyData * RankingUtils.wordRelevancy queryTerms, title, title
+
# A completer which calls filter() on many completers, aggregates the results, ranks them, and returns the top
# 10. All queries from the vomnibar come through a multi completer.
class MultiCompleter