mirror of
				https://github.com/zadam/trilium.git
				synced 2025-10-30 19:19:03 +01:00 
			
		
		
		
	searching now works correctly in inherited attributes
This commit is contained in:
		
							parent
							
								
									29e6b63f82
								
							
						
					
					
						commit
						ccb5f3ee18
					
				| @ -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('/') | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 zadam
						zadam