1
1
Fork 0
mirror of https://github.com/zadam/trilium.git synced 2025-01-24 16:10:48 +08:00

searching now works correctly in inherited attributes

This commit is contained in:
zadam 2020-05-13 00:01:10 +02:00
parent 29e6b63f82
commit ccb5f3ee18

View file

@ -29,6 +29,8 @@ class Note {
this.isProtected = !!row.isProtected;
/** @param {Note[]} */
this.parents = [];
/** @param {Note[]} */
this.children = [];
/** @param {Attribute[]} */
this.ownedAttributes = [];
}
@ -60,6 +62,14 @@ class Note {
return noteAttributeCache[this.noteId];
}
addSubTreeNoteIdsTo(noteIdSet) {
noteIdSet.add(this.noteId);
for (const child of this.children) {
child.addSubTreeNoteIdsTo(noteIdSet);
}
}
/** @return {Attribute[]} */
get inheritableAttributes() {
return this.attributes.filter(attr => attr.isInheritable);
@ -111,22 +121,11 @@ class Attribute {
/** @param {string} */
this.value = row.value;
/** @param {boolean} */
this.isInheritable = row.isInheritable;
this.isInheritable = !!row.isInheritable;
}
}
class FulltextReference {
/**
* @param type - attributeName, attributeValue, title
* @param noteId
*/
constructor(type, noteId) {
this.type = type;
this.noteId = noteId;
}
}
/** @type {Object.<String, FulltextReference>} */
/** @type {Object.<String, String>} */
let fulltext = {};
/** @type {Object.<String, AttributeMeta>} */
@ -195,17 +194,21 @@ async function getMappedRows(query, cb) {
return map;
}
function updateFulltext(note) {
let ft = note.title.toLowerCase();
for (const attr of note.attributes) {
ft += '|' + attr.name.toLowerCase();
ft += '|' + attr.value.toLowerCase();
}
fulltext[note.noteId] = ft;
}
async function load() {
notes = await getMappedRows(`SELECT noteId, title, isProtected FROM notes WHERE isDeleted = 0`,
row => new Note(row));
for (const note of Object.values(notes)) {
const title = note.title.toLowerCase();
fulltext[title] = fulltext[title] || [];
fulltext[title].push(new FulltextReference('note', note.noteId));
}
branches = await getMappedRows(`SELECT branchId, noteId, parentNoteId, prefix FROM branches WHERE isDeleted = 0`,
row => new Branch(row));
@ -213,17 +216,9 @@ async function load() {
row => new Attribute(row));
for (const attr of Object.values(attributes)) {
notes[attr.noteId].attributes.push(attr);
notes[attr.noteId].ownedAttributes.push(attr);
addToAttributeMeta(attributes);
const attrName = attr.name.toLowerCase();
fulltext[attrName] = fulltext[attrName] || [];
fulltext[attrName].push(new FulltextReference('aName', attr.noteId));
const attrValue = attr.value.toLowerCase();
fulltext[attrValue] = fulltext[attrValue] || [];
fulltext[attrValue].push(new FulltextReference('aVal', attr.noteId));
}
for (const branch of Object.values(branches)) {
@ -232,13 +227,16 @@ async function load() {
}
const childNote = notes[branch.noteId];
const parentNote = branch.parentNote;
if (!childNote) {
console.log(`Cannot find child note ${branch.noteId} of a branch ${branch.branchId}`);
continue;
}
childNote.parents.push(branch.parentNote);
childNote.parents.push(parentNote);
parentNote.children.push(childNote);
childParentToBranch[`${branch.noteId}-${branch.parentNoteId}`] = branch;
}
@ -246,6 +244,10 @@ async function load() {
await decryptProtectedNotes();
}
for (const note of Object.values(notes)) {
updateFulltext(note);
}
loaded = true;
loadedPromiseResolve();
}
@ -295,7 +297,7 @@ function highlightResults(results, allTokens) {
}
async function findNotes(query) {
if (!noteTitles || !query.length) {
if (!query.length) {
return [];
}
@ -310,15 +312,31 @@ async function findNotes(query) {
const matchedNoteIds = new Set();
for (const token of tokens) {
for (const chunk in fulltext) {
if (chunk.includes(token)) {
for (const fulltextReference of fulltext[chunk]) {
matchedNoteIds.add(fulltextReference.noteId);
}
for (const noteId in fulltext) {
if (!fulltext[noteId].includes(token)) {
continue;
}
matchedNoteIds.add(noteId);
const note = notes[noteId];
const inheritableAttrs = note.ownedAttributes.filter(attr => attr.isInheritable);
searchingAttrs:
for (const attr of inheritableAttrs) {
const lcName = attr.name.toLowerCase();
const lcValue = attr.value.toLowerCase();
for (const token of tokens) {
if (lcName.includes(token) || lcValue.includes(token)) {
note.addSubTreeNoteIdsTo(matchedNoteIds);
break searchingAttrs;
}
}
}
}
}
//console.log(matchedNoteIds);
// now we have set of noteIds which match at least one token
let results = [];
@ -339,9 +357,10 @@ async function findNotes(query) {
const foundAttrTokens = [];
for (const attribute of note.attributes) {
for (const attribute of note.ownedAttributes) {
for (const token of tokens) {
if (attribute.name.includes(token) || attribute.value.includes(token)) {
if (attribute.name.toLowerCase().includes(token)
|| attribute.value.toLowerCase().includes(token)) {
foundAttrTokens.push(token);
}
}
@ -423,9 +442,20 @@ function search(note, tokens, path, results) {
return;
}
const foundAttrTokens = [];
for (const attribute of note.ownedAttributes) {
for (const token of tokens) {
if (attribute.name.toLowerCase().includes(token)
|| attribute.value.toLowerCase().includes(token)) {
foundAttrTokens.push(token);
}
}
}
for (const parentNote of note.parents) {
const title = getNoteTitle(note.noteId, parentNote.noteId).toLowerCase();
const foundTokens = [];
const foundTokens = foundAttrTokens.slice();
for (const token of tokens) {
if (title.includes(token)) {
@ -592,15 +622,16 @@ function getSomePath(note, path = []) {
}
function getNotePath(noteId) {
const retPath = getSomePath(noteId);
const note = notes[noteId];
const retPath = getSomePath(note);
if (retPath) {
const noteTitle = getNoteTitleForPath(retPath);
const parentNoteId = childToParent[noteId][0];
const parentNote = note.parents[0];
return {
noteId: noteId,
branchId: childParentToBranchId[`${noteId}-${parentNoteId}`],
branchId: getBranch(noteId, parentNote.noteId).branchId,
title: noteTitle,
notePath: retPath,
path: retPath.join('/')