diff --git a/src/services/build_search_query.js b/src/services/build_search_query.js index f46b7474e..efd549140 100644 --- a/src/services/build_search_query.js +++ b/src/services/build_search_query.js @@ -67,8 +67,8 @@ module.exports = function(filters, selectedColumns = 'notes.*') { const params = []; for (const filter of filters) { - if (['orderby', 'limit'].includes(filter.name.toLowerCase())) { - continue; // orderby and limit are not real filters + if (['isarchived', 'orderby', 'limit'].includes(filter.name.toLowerCase())) { + continue; // these are not real filters } where += " " + filter.relation + " "; diff --git a/src/services/note_cache.js b/src/services/note_cache.js index ba088e33c..3c628e0b8 100644 --- a/src/services/note_cache.js +++ b/src/services/note_cache.js @@ -166,7 +166,7 @@ async function findNotes(query) { return apiResults; } -function isArchived(notePath) { +function isNotePathArchived(notePath) { // if the note is archived directly if (archived[notePath[notePath.length - 1]] !== undefined) { return true; @@ -182,11 +182,23 @@ function isArchived(notePath) { return false; } +/** + * This assumes that note is available. "archived" note means that there isn't a single non-archived note-path + * leading to this note. + * + * @param noteId + */ +function isArchived(noteId) { + const notePath = getSomePath(noteId); + + return isNotePathArchived(notePath); +} + function search(noteId, tokens, path, results) { if (tokens.length === 0) { const retPath = getSomePath(noteId, path); - if (retPath && !isArchived(retPath)) { + if (retPath && !isNotePathArchived(retPath)) { const thisNoteId = retPath[retPath.length - 1]; const thisParentNoteId = retPath[retPath.length - 2]; @@ -320,7 +332,7 @@ function getSomePath(noteId, path = []) { function getNotePath(noteId) { const retPath = getSomePath(noteId); - if (retPath && !isArchived(retPath)) { + if (retPath) { const noteTitle = getNoteTitleForPath(retPath); const parentNoteId = childToParent[noteId][0]; @@ -344,7 +356,7 @@ function evaluateSimilarity(text1, text2, noteId, results) { return; } - if (isArchived(notePath)) { + if (isNotePathArchived(notePath)) { coeff -= 0.2; // archived penalization } @@ -449,7 +461,7 @@ function resortChildToParent(noteId) { /** * @param noteId - * @returns {boolean} - true if note exists (is not deleted) and is not archived. + * @returns {boolean} - true if note exists (is not deleted) and is available in current note hoisting */ function isAvailable(noteId) { const notePath = getNotePath(noteId); @@ -470,6 +482,7 @@ module.exports = { getNotePath, getNoteTitleForPath, isAvailable, + isArchived, load, findSimilarNotes }; \ No newline at end of file diff --git a/src/services/parse_filters.js b/src/services/parse_filters.js index c46cd207b..ea2a142f4 100644 --- a/src/services/parse_filters.js +++ b/src/services/parse_filters.js @@ -74,6 +74,12 @@ module.exports = function (searchText) { } } + filters.push({ + relation: 'and', + name: 'isArchived', + operator: 'not-exists' + }); + filters.push({ relation: 'or', name: 'noteId', diff --git a/src/services/search.js b/src/services/search.js index dd076b001..7f533363d 100644 --- a/src/services/search.js +++ b/src/services/search.js @@ -17,19 +17,33 @@ async function searchForNoteIds(searchString) { const {query, params} = buildSearchQuery(filters, 'notes.noteId'); try { - const noteIds = await sql.getColumn(query, params); + let noteIds = await sql.getColumn(query, params); - const availableNoteIds = noteIds.filter(noteCacheService.isAvailable); + noteIds = noteIds.filter(noteCacheService.isAvailable); + + const isArchivedFilter = filters.find(filter => filter.name.toLowerCase() === 'isarchived'); + + if (isArchivedFilter) {console.log(isArchivedFilter); + if (isArchivedFilter.operator === 'exists') { + noteIds = noteIds.filter(noteCacheService.isArchived); + } + else if (isArchivedFilter.operator === 'not-exists') { + noteIds = noteIds.filter(noteId => !noteCacheService.isArchived(noteId)); + } + else { + throw new Error(`Unrecognized isArchived operator ${isArchivedFilter.operator}`); + } + } const limitFilter = filters.find(filter => filter.name.toLowerCase() === 'limit'); if (limitFilter) { const limit = parseInt(limitFilter.value); - return availableNoteIds.splice(0, limit); + return noteIds.splice(0, limit); } else { - return availableNoteIds; + return noteIds; } }