sorting search results occurences in the note title

This commit is contained in:
zadam 2020-12-11 13:54:41 +01:00
parent 0b6fa4ab06
commit be543737a9
16 changed files with 66 additions and 33 deletions

6
package-lock.json generated
View File

@ -4325,9 +4325,9 @@
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
},
"ini": {
"version": "1.3.5",
"resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz",
"integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw=="
"version": "1.3.7",
"resolved": "https://registry.npmjs.org/ini/-/ini-1.3.7.tgz",
"integrity": "sha512-iKpRpXP+CrP2jyrxvg1kMUpXDyRUFDWurxbnVT1vQPx+Wz9uCYsMIqYuSBLV+PAaZG/d7kRLKRFc9oDMsH+mFQ=="
},
"interpret": {
"version": "2.2.0",

View File

@ -47,7 +47,7 @@
"http-proxy-agent": "4.0.1",
"https-proxy-agent": "5.0.0",
"image-type": "4.1.0",
"ini": "1.3.5",
"ini": "1.3.7",
"is-svg": "4.2.1",
"jimp": "0.16.1",
"jsdom": "^16.4.0",

View File

@ -18,9 +18,9 @@ class AndExp extends Expression {
this.subExpressions = subExpressions;
}
execute(inputNoteSet, searchContext) {
execute(inputNoteSet, executionContext) {
for (const subExpression of this.subExpressions) {
inputNoteSet = subExpression.execute(inputNoteSet, searchContext);
inputNoteSet = subExpression.execute(inputNoteSet, executionContext);
}
return inputNoteSet;

View File

@ -10,14 +10,14 @@ class ChildOfExp extends Expression {
this.subExpression = subExpression;
}
execute(inputNoteSet, searchContext) {
execute(inputNoteSet, executionContext) {
const subInputNoteSet = new NoteSet();
for (const note of inputNoteSet.notes) {
subInputNoteSet.addAll(note.parents);
}
const subResNoteSet = this.subExpression.execute(subInputNoteSet, searchContext);
const subResNoteSet = this.subExpression.execute(subInputNoteSet, executionContext);
const resNoteSet = new NoteSet();

View File

@ -11,9 +11,9 @@ class DescendantOfExp extends Expression {
this.subExpression = subExpression;
}
execute(inputNoteSet, searchContext) {
execute(inputNoteSet, executionContext) {
const subInputNoteSet = new NoteSet(Object.values(noteCache.notes));
const subResNoteSet = this.subExpression.execute(subInputNoteSet, searchContext);
const subResNoteSet = this.subExpression.execute(subInputNoteSet, executionContext);
const subTreeNoteSet = new NoteSet();

View File

@ -3,10 +3,10 @@
class Expression {
/**
* @param {NoteSet} inputNoteSet
* @param {object} searchContext
* @param {object} executionContext
* @return {NoteSet}
*/
execute(inputNoteSet, searchContext) {}
execute(inputNoteSet, executionContext) {}
}
module.exports = Expression;

View File

@ -9,8 +9,8 @@ class NotExp extends Expression {
this.subExpression = subExpression;
}
execute(inputNoteSet, searchContext) {
const subNoteSet = this.subExpression.execute(inputNoteSet, searchContext);
execute(inputNoteSet, executionContext) {
const subNoteSet = this.subExpression.execute(inputNoteSet, executionContext);
return inputNoteSet.minus(subNoteSet);
}

View File

@ -11,7 +11,7 @@ class NoteCacheFlatTextExp extends Expression {
this.tokens = tokens;
}
execute(inputNoteSet, searchContext) {
execute(inputNoteSet, executionContext) {
// has deps on SQL which breaks unit test so needs to be dynamically required
const noteCacheService = require('../../note_cache/note_cache_service');
const resultNoteSet = new NoteSet();
@ -22,7 +22,7 @@ class NoteCacheFlatTextExp extends Expression {
if (retPath) {
const noteId = retPath[retPath.length - 1];
searchContext.noteIdToNotePath[noteId] = retPath;
executionContext.noteIdToNotePath[noteId] = retPath;
resultNoteSet.add(noteCache.notes[noteId]);
}

View File

@ -21,11 +21,11 @@ class OrExp extends Expression {
this.subExpressions = subExpressions;
}
execute(inputNoteSet, searchContext) {
execute(inputNoteSet, executionContext) {
const resultNoteSet = new NoteSet();
for (const subExpression of this.subExpressions) {
resultNoteSet.mergeIn(subExpression.execute(inputNoteSet, searchContext));
resultNoteSet.mergeIn(subExpression.execute(inputNoteSet, executionContext));
}
return resultNoteSet;

View File

@ -20,8 +20,8 @@ class OrderByAndLimitExp extends Expression {
this.subExpression = null; // it's expected to be set after construction
}
execute(inputNoteSet, searchContext) {
let {notes} = this.subExpression.execute(inputNoteSet, searchContext);
execute(inputNoteSet, executionContext) {
let {notes} = this.subExpression.execute(inputNoteSet, executionContext);
notes.sort((a, b) => {
for (const {valueExtractor, smaller, larger} of this.orderDefinitions) {

View File

@ -10,14 +10,14 @@ class ParentOfExp extends Expression {
this.subExpression = subExpression;
}
execute(inputNoteSet, searchContext) {
execute(inputNoteSet, executionContext) {
const subInputNoteSet = new NoteSet();
for (const note of inputNoteSet.notes) {
subInputNoteSet.addAll(note.children);
}
const subResNoteSet = this.subExpression.execute(subInputNoteSet, searchContext);
const subResNoteSet = this.subExpression.execute(subInputNoteSet, executionContext);
const resNoteSet = new NoteSet();

View File

@ -37,7 +37,7 @@ class PropertyComparisonExp extends Expression {
this.comparator = comparator;
}
execute(inputNoteSet, searchContext) {
execute(inputNoteSet, executionContext) {
const resNoteSet = new NoteSet();
for (const note of inputNoteSet.notes) {

View File

@ -12,7 +12,7 @@ class RelationWhereExp extends Expression {
this.subExpression = subExpression;
}
execute(inputNoteSet, searchContext) {
execute(inputNoteSet, executionContext) {
const candidateNoteSet = new NoteSet();
for (const attr of noteCache.findAttributes('relation', this.relationName)) {
@ -20,7 +20,7 @@ class RelationWhereExp extends Expression {
if (inputNoteSet.hasNoteId(note.noteId)) {
const subInputNoteSet = new NoteSet([attr.targetNote]);
const subResNoteSet = this.subExpression.execute(subInputNoteSet, searchContext);
const subResNoteSet = this.subExpression.execute(subInputNoteSet, executionContext);
if (subResNoteSet.hasNote(attr.targetNote)) {
if (attr.isInheritable) {

View File

@ -12,7 +12,7 @@ class SubTreeExp extends Expression {
this.subTreeNoteId = subTreeNoteId;
}
execute(inputNoteSet, searchContext) {
execute(inputNoteSet, executionContext) {
const subTreeNote = noteCache.notes[this.subTreeNoteId];
if (!subTreeNote) {

View File

@ -15,6 +15,26 @@ class SearchResult {
get noteId() {
return this.notePathArray[this.notePathArray.length - 1];
}
computeScore(tokens) {
this.score = 0;
const chunks = this.notePathTitle.toLowerCase().split(" ");
for (const chunk of chunks) {
for (const token of tokens) {
if (chunk === token) {
this.score += 4 * token.length;
}
else if (chunk.startsWith(token)) {
this.score += 2 * token.length;
}
else if (chunk.includes(token)) {
this.score += token.length;
}
}
}
}
}
module.exports = SearchResult;

View File

@ -13,9 +13,10 @@ const cls = require('../../cls.js');
/**
* @param {Expression} expression
* @param {SearchContext} searchContext
* @return {SearchResult[]}
*/
function findNotesWithExpression(expression) {
function findNotesWithExpression(expression, searchContext) {
const hoistedNote = noteCache.notes[cls.getHoistedNoteId()];
let allNotes = (hoistedNote && hoistedNote.noteId !== 'root')
? hoistedNote.subtreeNotes
@ -27,27 +28,39 @@ function findNotesWithExpression(expression) {
const allNoteSet = new NoteSet(allNotes);
const searchContext = {
const executionContext = {
noteIdToNotePath: {}
};
const noteSet = expression.execute(allNoteSet, searchContext);
const noteSet = expression.execute(allNoteSet, executionContext);
const searchResults = noteSet.notes
.map(note => searchContext.noteIdToNotePath[note.noteId] || noteCacheService.getSomePath(note))
.map(note => executionContext.noteIdToNotePath[note.noteId] || noteCacheService.getSomePath(note))
.filter(notePathArray => notePathArray.includes(cls.getHoistedNoteId()))
.map(notePathArray => new SearchResult(notePathArray));
for (const res of searchResults) {
res.computeScore(searchContext.highlightedTokens);
}
if (!noteSet.sorted) {
// sort results by depth of the note. This is based on the assumption that more important results
// are closer to the note root.
searchResults.sort((a, b) => {
if (a.score > b.score) {
return -1;
} else if (a.score < b.score) {
return 1;
}
// if score does not decide then sort results by depth of the note.
// This is based on the assumption that more important results are closer to the note root.
if (a.notePathArray.length === b.notePathArray.length) {
return a.notePathTitle < b.notePathTitle ? -1 : 1;
}
return a.notePathArray.length < b.notePathArray.length ? -1 : 1;
});
}
return searchResults;
@ -86,7 +99,7 @@ function findNotesWithQuery(query, searchContext) {
return [];
}
return findNotesWithExpression(expression);
return findNotesWithExpression(expression, searchContext);
}, 20);
}