From 208d16b2ef03160e3aec01b24423571cfe59218b Mon Sep 17 00:00:00 2001 From: Nico Rehwaldt Date: Thu, 21 Nov 2024 15:10:17 +0100 Subject: [PATCH] chore(search): value based off token length This gives longer matches precedence. chore(search): penalize unmatched tokens This ensures we score "most relevant" results higher. --- lib/features/search/search.js | 31 ++++++++++++++----------- test/spec/features/search/searchSpec.js | 30 ++++++++++++++++++++++-- 2 files changed, 46 insertions(+), 15 deletions(-) diff --git a/lib/features/search/search.js b/lib/features/search/search.js index 8def8ee5d..7c7dfdd12 100644 --- a/lib/features/search/search.js +++ b/lib/features/search/search.js @@ -163,28 +163,33 @@ function scoreTokens(tokens) { } /** - * Score a token. + * Score a token based on its characteristics + * and the length of the matched content. * * @param { Token } token * * @returns { number } */ function scoreToken(token) { + const modifier = Math.log(token.value.length); + if (!token.match) { - return 0; + return -0.07 * modifier; } - return token.start - ? ( - token.end - ? 131.9 - : 7.87 - ) - : ( - token.wordStart - ? 2.19 - : 1 - ); + return ( + token.start + ? ( + token.end + ? 131.9 + : 7.87 + ) + : ( + token.wordStart + ? 2.19 + : 1 + ) + ) * modifier; } /** diff --git a/test/spec/features/search/searchSpec.js b/test/spec/features/search/searchSpec.js index ffa9f57c1..383185ffd 100644 --- a/test/spec/features/search/searchSpec.js +++ b/test/spec/features/search/searchSpec.js @@ -223,13 +223,13 @@ describe('features/search', function() { title: 'foo bar' }, { - title: 'foo baz and very long additional text\nalso foo bar' + title: 'foo bar baz' }, { title: 'baz and very long foo bar bar bar\nalso foo bar' }, { - title: 'foo bar baz' + title: 'foo baz and very long additional text\nalso foo bar' }, { title: 'baz foo bar' @@ -253,6 +253,32 @@ describe('features/search', function() { })); + it('should prioritize longest match', inject(function(search) { + + // given + const items = [ + { + title: 'yes foowoo' + }, + { + title: 'yeskay foowoo' + } + ]; + + // when + const results = search(items, 'yes foo', { + keys: [ + 'title' + ] + }); + + // then + expect(results).to.have.length(2); + expect(results[0].item).to.eql(items[0]); + expect(results[1].item).to.eql(items[1]); + })); + + it('should prioritize start of term', inject(function(search) { // given