From 797ddf6205a9b197adda387241e6da1541214faf Mon Sep 17 00:00:00 2001 From: zadam Date: Fri, 30 Dec 2022 23:14:48 +0100 Subject: [PATCH] search hit with exact note title match gets a strong score boost, closes #3470 --- src/routes/api/attributes.js | 2 -- src/services/search/search_context.js | 1 + src/services/search/search_result.js | 16 ++++++++++------ src/services/search/services/lex.js | 6 ++++++ src/services/search/services/search.js | 6 ++++-- 5 files changed, 21 insertions(+), 10 deletions(-) diff --git a/src/routes/api/attributes.js b/src/routes/api/attributes.js index cb59239a9..8c0299b7a 100644 --- a/src/routes/api/attributes.js +++ b/src/routes/api/attributes.js @@ -68,8 +68,6 @@ function updateNoteAttribute(req) { attribute.markAsDeleted(); } - console.log(attribute); - attribute.save(); return { diff --git a/src/services/search/search_context.js b/src/services/search/search_context.js index c71addb17..6c427cf5f 100644 --- a/src/services/search/search_context.js +++ b/src/services/search/search_context.js @@ -24,6 +24,7 @@ class SearchContext { this.fuzzyAttributeSearch = !!params.fuzzyAttributeSearch; this.highlightedTokens = []; this.originalQuery = ""; + this.fulltextQuery = ""; // complete fulltext part // if true, becca does not have (up-to-date) information needed to process the query // and some extra data needs to be loaded before executing this.dbLoadNeeded = false; diff --git a/src/services/search/search_result.js b/src/services/search/search_result.js index 15b036e9a..4c678661d 100644 --- a/src/services/search/search_result.js +++ b/src/services/search/search_result.js @@ -17,18 +17,22 @@ class SearchResult { return this.notePathArray[this.notePathArray.length - 1]; } - computeScore(tokens) { + computeScore(fulltextQuery, tokens) { this.score = 0; + const note = becca.notes[this.noteId]; + + if (note.title.toLowerCase() === fulltextQuery) { + this.score += 100; // high reward for exact match #3470 + } + + // notes with matches on its own note title as opposed to ancestors or descendants + this.addScoreForStrings(tokens, note.title, 1.5); + // matches in attributes don't get extra points and thus are implicitly valued less than note path matches this.addScoreForStrings(tokens, this.notePathTitle, 1); - // add one more time for note title alone (already contained in the notePathTitle), - // thus preferring notes with matches on its own note title as opposed to ancestors or descendants - const note = becca.notes[this.noteId]; - this.addScoreForStrings(tokens, note.title, 1.5); - if (note.isInHiddenSubtree()) { this.score = this.score / 2; } diff --git a/src/services/search/services/lex.js b/src/services/search/services/lex.js index d7a3fb83e..c3c2273eb 100644 --- a/src/services/search/services/lex.js +++ b/src/services/search/services/lex.js @@ -1,6 +1,7 @@ function lex(str) { str = str.toLowerCase(); + let fulltextQuery = ""; const fulltextTokens = []; const expressionTokens = []; @@ -37,6 +38,8 @@ function lex(str) { expressionTokens.push(rec); } else { fulltextTokens.push(rec); + + fulltextQuery = str.substr(0, endIndex + 1); } currentWord = ''; @@ -129,7 +132,10 @@ function lex(str) { finishWord(str.length - 1); + fulltextQuery = fulltextQuery.trim(); + return { + fulltextQuery, fulltextTokens, expressionTokens } diff --git a/src/services/search/services/search.js b/src/services/search/services/search.js index 206ec63b4..3e2f5af40 100644 --- a/src/services/search/services/search.js +++ b/src/services/search/services/search.js @@ -170,7 +170,7 @@ function findResultsWithExpression(expression, searchContext) { .filter(note => !!note); for (const res of searchResults) { - res.computeScore(searchContext.highlightedTokens); + res.computeScore(searchContext.fulltextQuery, searchContext.highlightedTokens); } if (!noteSet.sorted) { @@ -195,7 +195,9 @@ function findResultsWithExpression(expression, searchContext) { } function parseQueryToExpression(query, searchContext) { - const {fulltextTokens, expressionTokens} = lex(query); + const {fulltextQuery, fulltextTokens, expressionTokens} = lex(query); + searchContext.fulltextQuery = fulltextQuery; + let structuredExpressionTokens; try {