diff --git a/docs/backend_api/BackendScriptApi.html b/docs/backend_api/BackendScriptApi.html
index fb02df5ea..f970bf8b3 100644
--- a/docs/backend_api/BackendScriptApi.html
+++ b/docs/backend_api/BackendScriptApi.html
@@ -394,7 +394,7 @@ the backend.
Source:
@@ -758,7 +758,7 @@ the backend.
Source:
@@ -1044,7 +1044,7 @@ the backend.
Source:
@@ -1224,7 +1224,7 @@ the backend.
Source:
@@ -1423,7 +1423,7 @@ the backend.
Source:
@@ -1523,7 +1523,7 @@ the backend.
Source:
@@ -1981,7 +1981,7 @@ the backend.
Source:
@@ -2739,7 +2739,7 @@ if some action needs to happen on only one specific instance.
Source:
@@ -3084,7 +3084,7 @@ if some action needs to happen on only one specific instance.
Source:
@@ -3280,7 +3280,7 @@ if some action needs to happen on only one specific instance.
Source:
@@ -3384,7 +3384,7 @@ if some action needs to happen on only one specific instance.
Source:
@@ -3560,7 +3560,7 @@ if some action needs to happen on only one specific instance.
Source:
@@ -3713,7 +3713,7 @@ if some action needs to happen on only one specific instance.
Source:
@@ -3861,7 +3861,7 @@ if some action needs to happen on only one specific instance.
Source:
@@ -3891,6 +3891,160 @@ if some action needs to happen on only one specific instance.
+
+
+
+
+ searchForNote(searchString) → {Promise.<(Note|null)>}
+
+
+
+
+
+
+
+ This is a powerful search method - you can search by attributes and their values, e.g.:
+"@dateModified =* MONTH AND @log". See full documentation for all options at: https://github.com/zadam/trilium/wiki/Search
+
+
+
+
+
+
+
+
+
+
+ Parameters:
+
+
+
+
+
+
+ Name |
+
+
+ Type |
+
+
+
+
+
+ Description |
+
+
+
+
+
+
+
+
+ searchString |
+
+
+
+
+
+string
+
+
+
+ |
+
+
+
+
+
+ |
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ - Source:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Returns:
+
+
+
+
+
+ -
+ Type
+
+ -
+
+Promise.<(Note|null)>
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -4023,10 +4177,6 @@ if some action needs to happen on only one specific instance.
Returns:
-
- $
-
-
@@ -4231,7 +4381,7 @@ This method looks similar to toggleNoteInParent() but differs because we're look
- Source:
@@ -4362,7 +4512,7 @@ This method looks similar to toggleNoteInParent() but differs because we're look
- Source:
@@ -4576,7 +4726,7 @@ This method looks similar to toggleNoteInParent() but differs because we're look
- Source:
@@ -4733,7 +4883,7 @@ transactional by default.
- Source:
diff --git a/docs/backend_api/global.html b/docs/backend_api/global.html
index 40d6e0b4e..193c5d8ab 100644
--- a/docs/backend_api/global.html
+++ b/docs/backend_api/global.html
@@ -272,7 +272,7 @@
- Source:
@@ -558,7 +558,7 @@
- Source:
diff --git a/docs/backend_api/services_backend_script_api.js.html b/docs/backend_api/services_backend_script_api.js.html
index 5303b0d7b..f44d49001 100644
--- a/docs/backend_api/services_backend_script_api.js.html
+++ b/docs/backend_api/services_backend_script_api.js.html
@@ -127,10 +127,24 @@ function BackendScriptApi(currentNote, apiParams) {
*
* @method
* @param {string} searchString
- * @returns ${Promise<Note[]>}
+ * @returns {Promise<Note[]>}
*/
this.searchForNotes = searchService.searchForNotes;
+ /**
+ * This is a powerful search method - you can search by attributes and their values, e.g.:
+ * "@dateModified =* MONTH AND @log". See full documentation for all options at: https://github.com/zadam/trilium/wiki/Search
+ *
+ * @method
+ * @param {string} searchString
+ * @returns {Promise<Note|null>}
+ */
+ this.searchForNote = async searchString => {
+ const notes = await searchService.searchForNotes(searchString);
+
+ return notes.length > 0 ? notes[0] : null;
+ };
+
/**
* Retrieves notes with given label name & value
*
diff --git a/src/services/backend_script_api.js b/src/services/backend_script_api.js
index fd56156e0..9de17d977 100644
--- a/src/services/backend_script_api.js
+++ b/src/services/backend_script_api.js
@@ -99,10 +99,24 @@ function BackendScriptApi(currentNote, apiParams) {
*
* @method
* @param {string} searchString
- * @returns ${Promise}
+ * @returns {Promise}
*/
this.searchForNotes = searchService.searchForNotes;
+ /**
+ * This is a powerful search method - you can search by attributes and their values, e.g.:
+ * "@dateModified =* MONTH AND @log". See full documentation for all options at: https://github.com/zadam/trilium/wiki/Search
+ *
+ * @method
+ * @param {string} searchString
+ * @returns {Promise}
+ */
+ this.searchForNote = async searchString => {
+ const notes = await searchService.searchForNotes(searchString);
+
+ return notes.length > 0 ? notes[0] : null;
+ };
+
/**
* Retrieves notes with given label name & value
*
diff --git a/src/services/build_search_query.js b/src/services/build_search_query.js
index 9ec202423..f46b7474e 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 (filter.name.toLowerCase() === 'orderby') {
- continue; // orderby is not real filter
+ if (['orderby', 'limit'].includes(filter.name.toLowerCase())) {
+ continue; // orderby and limit are not real filters
}
where += " " + filter.relation + " ";
diff --git a/src/services/note_cache.js b/src/services/note_cache.js
index 60e6e0003..59f249f41 100644
--- a/src/services/note_cache.js
+++ b/src/services/note_cache.js
@@ -376,6 +376,16 @@ eventService.subscribe([eventService.ENTITY_CHANGED, eventService.ENTITY_DELETED
}
});
+/**
+ * @param noteId
+ * @returns {boolean} - true if note exists (is not deleted) and is not archived.
+ */
+function isAvailable(noteId) {
+ const notePath = getNotePath(noteId);
+
+ return !!notePath;
+}
+
eventService.subscribe(eventService.ENTER_PROTECTED_SESSION, () => {
if (loaded) {
loadProtectedNotes();
@@ -388,5 +398,6 @@ module.exports = {
findNotes,
getNotePath,
getNoteTitleForPath,
+ isAvailable,
load
};
\ No newline at end of file
diff --git a/src/services/repository.js b/src/services/repository.js
index 45c004ee4..ccbebdd30 100644
--- a/src/services/repository.js
+++ b/src/services/repository.js
@@ -42,6 +42,21 @@ async function getNote(noteId) {
return await getEntity("SELECT * FROM notes WHERE noteId = ?", [noteId]);
}
+/** @returns {Promise} */
+async function getNotes(noteIds) {
+ // this note might be optimised, but remember that it must keep the existing order of noteIds
+ // (important e.g. for @orderBy in search)
+ const notes = [];
+
+ for (const noteId of noteIds) {
+ const note = await getNote(noteId);
+
+ notes.push(note);
+ }
+
+ return notes;
+}
+
/** @returns {Promise} */
async function getBranch(branchId) {
return await getEntity("SELECT * FROM branches WHERE branchId = ?", [branchId]);
@@ -125,6 +140,7 @@ module.exports = {
getEntities,
getEntity,
getNote,
+ getNotes,
getBranch,
getAttribute,
getOption,
diff --git a/src/services/search.js b/src/services/search.js
index 2ef975e08..dd076b001 100644
--- a/src/services/search.js
+++ b/src/services/search.js
@@ -3,20 +3,12 @@ const sql = require('./sql');
const log = require('./log');
const parseFilters = require('./parse_filters');
const buildSearchQuery = require('./build_search_query');
+const noteCacheService = require('./note_cache');
async function searchForNotes(searchString) {
- const filters = parseFilters(searchString);
+ const noteIds = await searchForNoteIds(searchString);
- const {query, params} = buildSearchQuery(filters);
-
- try {
- return await repository.getEntities(query, params);
- }
- catch (e) {
- log.error("Search failed for " + query);
-
- throw e;
- }
+ return await repository.getNotes(noteIds);
}
async function searchForNoteIds(searchString) {
@@ -25,7 +17,21 @@ async function searchForNoteIds(searchString) {
const {query, params} = buildSearchQuery(filters, 'notes.noteId');
try {
- return await sql.getColumn(query, params);
+ const noteIds = await sql.getColumn(query, params);
+
+ const availableNoteIds = noteIds.filter(noteCacheService.isAvailable);
+
+ const limitFilter = filters.find(filter => filter.name.toLowerCase() === 'limit');
+
+ if (limitFilter) {
+ const limit = parseInt(limitFilter.value);
+
+ return availableNoteIds.splice(0, limit);
+ }
+ else {
+ return availableNoteIds;
+ }
+
}
catch (e) {
log.error("Search failed for " + query);