mirror of
https://github.com/zadam/trilium.git
synced 2025-06-06 18:08:33 +02:00
sorting search results occurences in the note title
This commit is contained in:
parent
0b6fa4ab06
commit
be543737a9
6
package-lock.json
generated
6
package-lock.json
generated
@ -4325,9 +4325,9 @@
|
|||||||
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
|
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
|
||||||
},
|
},
|
||||||
"ini": {
|
"ini": {
|
||||||
"version": "1.3.5",
|
"version": "1.3.7",
|
||||||
"resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz",
|
"resolved": "https://registry.npmjs.org/ini/-/ini-1.3.7.tgz",
|
||||||
"integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw=="
|
"integrity": "sha512-iKpRpXP+CrP2jyrxvg1kMUpXDyRUFDWurxbnVT1vQPx+Wz9uCYsMIqYuSBLV+PAaZG/d7kRLKRFc9oDMsH+mFQ=="
|
||||||
},
|
},
|
||||||
"interpret": {
|
"interpret": {
|
||||||
"version": "2.2.0",
|
"version": "2.2.0",
|
||||||
|
@ -47,7 +47,7 @@
|
|||||||
"http-proxy-agent": "4.0.1",
|
"http-proxy-agent": "4.0.1",
|
||||||
"https-proxy-agent": "5.0.0",
|
"https-proxy-agent": "5.0.0",
|
||||||
"image-type": "4.1.0",
|
"image-type": "4.1.0",
|
||||||
"ini": "1.3.5",
|
"ini": "1.3.7",
|
||||||
"is-svg": "4.2.1",
|
"is-svg": "4.2.1",
|
||||||
"jimp": "0.16.1",
|
"jimp": "0.16.1",
|
||||||
"jsdom": "^16.4.0",
|
"jsdom": "^16.4.0",
|
||||||
|
@ -18,9 +18,9 @@ class AndExp extends Expression {
|
|||||||
this.subExpressions = subExpressions;
|
this.subExpressions = subExpressions;
|
||||||
}
|
}
|
||||||
|
|
||||||
execute(inputNoteSet, searchContext) {
|
execute(inputNoteSet, executionContext) {
|
||||||
for (const subExpression of this.subExpressions) {
|
for (const subExpression of this.subExpressions) {
|
||||||
inputNoteSet = subExpression.execute(inputNoteSet, searchContext);
|
inputNoteSet = subExpression.execute(inputNoteSet, executionContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
return inputNoteSet;
|
return inputNoteSet;
|
||||||
|
@ -10,14 +10,14 @@ class ChildOfExp extends Expression {
|
|||||||
this.subExpression = subExpression;
|
this.subExpression = subExpression;
|
||||||
}
|
}
|
||||||
|
|
||||||
execute(inputNoteSet, searchContext) {
|
execute(inputNoteSet, executionContext) {
|
||||||
const subInputNoteSet = new NoteSet();
|
const subInputNoteSet = new NoteSet();
|
||||||
|
|
||||||
for (const note of inputNoteSet.notes) {
|
for (const note of inputNoteSet.notes) {
|
||||||
subInputNoteSet.addAll(note.parents);
|
subInputNoteSet.addAll(note.parents);
|
||||||
}
|
}
|
||||||
|
|
||||||
const subResNoteSet = this.subExpression.execute(subInputNoteSet, searchContext);
|
const subResNoteSet = this.subExpression.execute(subInputNoteSet, executionContext);
|
||||||
|
|
||||||
const resNoteSet = new NoteSet();
|
const resNoteSet = new NoteSet();
|
||||||
|
|
||||||
|
@ -11,9 +11,9 @@ class DescendantOfExp extends Expression {
|
|||||||
this.subExpression = subExpression;
|
this.subExpression = subExpression;
|
||||||
}
|
}
|
||||||
|
|
||||||
execute(inputNoteSet, searchContext) {
|
execute(inputNoteSet, executionContext) {
|
||||||
const subInputNoteSet = new NoteSet(Object.values(noteCache.notes));
|
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();
|
const subTreeNoteSet = new NoteSet();
|
||||||
|
|
||||||
|
@ -3,10 +3,10 @@
|
|||||||
class Expression {
|
class Expression {
|
||||||
/**
|
/**
|
||||||
* @param {NoteSet} inputNoteSet
|
* @param {NoteSet} inputNoteSet
|
||||||
* @param {object} searchContext
|
* @param {object} executionContext
|
||||||
* @return {NoteSet}
|
* @return {NoteSet}
|
||||||
*/
|
*/
|
||||||
execute(inputNoteSet, searchContext) {}
|
execute(inputNoteSet, executionContext) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = Expression;
|
module.exports = Expression;
|
||||||
|
@ -9,8 +9,8 @@ class NotExp extends Expression {
|
|||||||
this.subExpression = subExpression;
|
this.subExpression = subExpression;
|
||||||
}
|
}
|
||||||
|
|
||||||
execute(inputNoteSet, searchContext) {
|
execute(inputNoteSet, executionContext) {
|
||||||
const subNoteSet = this.subExpression.execute(inputNoteSet, searchContext);
|
const subNoteSet = this.subExpression.execute(inputNoteSet, executionContext);
|
||||||
|
|
||||||
return inputNoteSet.minus(subNoteSet);
|
return inputNoteSet.minus(subNoteSet);
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ class NoteCacheFlatTextExp extends Expression {
|
|||||||
this.tokens = tokens;
|
this.tokens = tokens;
|
||||||
}
|
}
|
||||||
|
|
||||||
execute(inputNoteSet, searchContext) {
|
execute(inputNoteSet, executionContext) {
|
||||||
// has deps on SQL which breaks unit test so needs to be dynamically required
|
// has deps on SQL which breaks unit test so needs to be dynamically required
|
||||||
const noteCacheService = require('../../note_cache/note_cache_service');
|
const noteCacheService = require('../../note_cache/note_cache_service');
|
||||||
const resultNoteSet = new NoteSet();
|
const resultNoteSet = new NoteSet();
|
||||||
@ -22,7 +22,7 @@ class NoteCacheFlatTextExp extends Expression {
|
|||||||
|
|
||||||
if (retPath) {
|
if (retPath) {
|
||||||
const noteId = retPath[retPath.length - 1];
|
const noteId = retPath[retPath.length - 1];
|
||||||
searchContext.noteIdToNotePath[noteId] = retPath;
|
executionContext.noteIdToNotePath[noteId] = retPath;
|
||||||
|
|
||||||
resultNoteSet.add(noteCache.notes[noteId]);
|
resultNoteSet.add(noteCache.notes[noteId]);
|
||||||
}
|
}
|
||||||
|
@ -21,11 +21,11 @@ class OrExp extends Expression {
|
|||||||
this.subExpressions = subExpressions;
|
this.subExpressions = subExpressions;
|
||||||
}
|
}
|
||||||
|
|
||||||
execute(inputNoteSet, searchContext) {
|
execute(inputNoteSet, executionContext) {
|
||||||
const resultNoteSet = new NoteSet();
|
const resultNoteSet = new NoteSet();
|
||||||
|
|
||||||
for (const subExpression of this.subExpressions) {
|
for (const subExpression of this.subExpressions) {
|
||||||
resultNoteSet.mergeIn(subExpression.execute(inputNoteSet, searchContext));
|
resultNoteSet.mergeIn(subExpression.execute(inputNoteSet, executionContext));
|
||||||
}
|
}
|
||||||
|
|
||||||
return resultNoteSet;
|
return resultNoteSet;
|
||||||
|
@ -20,8 +20,8 @@ class OrderByAndLimitExp extends Expression {
|
|||||||
this.subExpression = null; // it's expected to be set after construction
|
this.subExpression = null; // it's expected to be set after construction
|
||||||
}
|
}
|
||||||
|
|
||||||
execute(inputNoteSet, searchContext) {
|
execute(inputNoteSet, executionContext) {
|
||||||
let {notes} = this.subExpression.execute(inputNoteSet, searchContext);
|
let {notes} = this.subExpression.execute(inputNoteSet, executionContext);
|
||||||
|
|
||||||
notes.sort((a, b) => {
|
notes.sort((a, b) => {
|
||||||
for (const {valueExtractor, smaller, larger} of this.orderDefinitions) {
|
for (const {valueExtractor, smaller, larger} of this.orderDefinitions) {
|
||||||
|
@ -10,14 +10,14 @@ class ParentOfExp extends Expression {
|
|||||||
this.subExpression = subExpression;
|
this.subExpression = subExpression;
|
||||||
}
|
}
|
||||||
|
|
||||||
execute(inputNoteSet, searchContext) {
|
execute(inputNoteSet, executionContext) {
|
||||||
const subInputNoteSet = new NoteSet();
|
const subInputNoteSet = new NoteSet();
|
||||||
|
|
||||||
for (const note of inputNoteSet.notes) {
|
for (const note of inputNoteSet.notes) {
|
||||||
subInputNoteSet.addAll(note.children);
|
subInputNoteSet.addAll(note.children);
|
||||||
}
|
}
|
||||||
|
|
||||||
const subResNoteSet = this.subExpression.execute(subInputNoteSet, searchContext);
|
const subResNoteSet = this.subExpression.execute(subInputNoteSet, executionContext);
|
||||||
|
|
||||||
const resNoteSet = new NoteSet();
|
const resNoteSet = new NoteSet();
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ class PropertyComparisonExp extends Expression {
|
|||||||
this.comparator = comparator;
|
this.comparator = comparator;
|
||||||
}
|
}
|
||||||
|
|
||||||
execute(inputNoteSet, searchContext) {
|
execute(inputNoteSet, executionContext) {
|
||||||
const resNoteSet = new NoteSet();
|
const resNoteSet = new NoteSet();
|
||||||
|
|
||||||
for (const note of inputNoteSet.notes) {
|
for (const note of inputNoteSet.notes) {
|
||||||
|
@ -12,7 +12,7 @@ class RelationWhereExp extends Expression {
|
|||||||
this.subExpression = subExpression;
|
this.subExpression = subExpression;
|
||||||
}
|
}
|
||||||
|
|
||||||
execute(inputNoteSet, searchContext) {
|
execute(inputNoteSet, executionContext) {
|
||||||
const candidateNoteSet = new NoteSet();
|
const candidateNoteSet = new NoteSet();
|
||||||
|
|
||||||
for (const attr of noteCache.findAttributes('relation', this.relationName)) {
|
for (const attr of noteCache.findAttributes('relation', this.relationName)) {
|
||||||
@ -20,7 +20,7 @@ class RelationWhereExp extends Expression {
|
|||||||
|
|
||||||
if (inputNoteSet.hasNoteId(note.noteId)) {
|
if (inputNoteSet.hasNoteId(note.noteId)) {
|
||||||
const subInputNoteSet = new NoteSet([attr.targetNote]);
|
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 (subResNoteSet.hasNote(attr.targetNote)) {
|
||||||
if (attr.isInheritable) {
|
if (attr.isInheritable) {
|
||||||
|
@ -12,7 +12,7 @@ class SubTreeExp extends Expression {
|
|||||||
this.subTreeNoteId = subTreeNoteId;
|
this.subTreeNoteId = subTreeNoteId;
|
||||||
}
|
}
|
||||||
|
|
||||||
execute(inputNoteSet, searchContext) {
|
execute(inputNoteSet, executionContext) {
|
||||||
const subTreeNote = noteCache.notes[this.subTreeNoteId];
|
const subTreeNote = noteCache.notes[this.subTreeNoteId];
|
||||||
|
|
||||||
if (!subTreeNote) {
|
if (!subTreeNote) {
|
||||||
|
@ -15,6 +15,26 @@ class SearchResult {
|
|||||||
get noteId() {
|
get noteId() {
|
||||||
return this.notePathArray[this.notePathArray.length - 1];
|
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;
|
module.exports = SearchResult;
|
||||||
|
@ -13,9 +13,10 @@ const cls = require('../../cls.js');
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {Expression} expression
|
* @param {Expression} expression
|
||||||
|
* @param {SearchContext} searchContext
|
||||||
* @return {SearchResult[]}
|
* @return {SearchResult[]}
|
||||||
*/
|
*/
|
||||||
function findNotesWithExpression(expression) {
|
function findNotesWithExpression(expression, searchContext) {
|
||||||
const hoistedNote = noteCache.notes[cls.getHoistedNoteId()];
|
const hoistedNote = noteCache.notes[cls.getHoistedNoteId()];
|
||||||
let allNotes = (hoistedNote && hoistedNote.noteId !== 'root')
|
let allNotes = (hoistedNote && hoistedNote.noteId !== 'root')
|
||||||
? hoistedNote.subtreeNotes
|
? hoistedNote.subtreeNotes
|
||||||
@ -27,27 +28,39 @@ function findNotesWithExpression(expression) {
|
|||||||
|
|
||||||
const allNoteSet = new NoteSet(allNotes);
|
const allNoteSet = new NoteSet(allNotes);
|
||||||
|
|
||||||
const searchContext = {
|
const executionContext = {
|
||||||
noteIdToNotePath: {}
|
noteIdToNotePath: {}
|
||||||
};
|
};
|
||||||
|
|
||||||
const noteSet = expression.execute(allNoteSet, searchContext);
|
const noteSet = expression.execute(allNoteSet, executionContext);
|
||||||
|
|
||||||
const searchResults = noteSet.notes
|
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()))
|
.filter(notePathArray => notePathArray.includes(cls.getHoistedNoteId()))
|
||||||
.map(notePathArray => new SearchResult(notePathArray));
|
.map(notePathArray => new SearchResult(notePathArray));
|
||||||
|
|
||||||
|
for (const res of searchResults) {
|
||||||
|
res.computeScore(searchContext.highlightedTokens);
|
||||||
|
}
|
||||||
|
|
||||||
if (!noteSet.sorted) {
|
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) => {
|
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) {
|
if (a.notePathArray.length === b.notePathArray.length) {
|
||||||
return a.notePathTitle < b.notePathTitle ? -1 : 1;
|
return a.notePathTitle < b.notePathTitle ? -1 : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return a.notePathArray.length < b.notePathArray.length ? -1 : 1;
|
return a.notePathArray.length < b.notePathArray.length ? -1 : 1;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return searchResults;
|
return searchResults;
|
||||||
@ -86,7 +99,7 @@ function findNotesWithQuery(query, searchContext) {
|
|||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
return findNotesWithExpression(expression);
|
return findNotesWithExpression(expression, searchContext);
|
||||||
}, 20);
|
}, 20);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user