trilium/src/routes/api/search.js

94 lines
2.6 KiB
JavaScript
Raw Normal View History

"use strict";
const sql = require('../../services/sql');
2019-02-16 04:21:26 +08:00
const utils = require('../../services/utils');
const noteService = require('../../services/notes');
2018-06-06 07:12:52 +08:00
const noteCacheService = require('../../services/note_cache');
const parseFilters = require('../../services/parse_filters');
const buildSearchQuery = require('../../services/build_search_query');
async function searchNotes(req) {
const {labelFilters, searchText} = parseFilters(req.params.searchString);
let labelFiltersNoteIds = null;
if (labelFilters.length > 0) {
const {query, params} = buildSearchQuery(labelFilters, searchText);
labelFiltersNoteIds = await sql.getColumn(query, params);
}
let searchTextResults = null;
if (searchText.trim().length > 0) {
searchTextResults = await noteCacheService.findNotes(searchText);
let fullTextNoteIds = await getFullTextResults(searchText);
for (const noteId of fullTextNoteIds) {
if (!searchTextResults.some(item => item.noteId === noteId)) {
2018-06-06 07:12:52 +08:00
const result = noteCacheService.getNotePath(noteId);
if (result) {
searchTextResults.push(result);
}
}
}
}
let results;
if (labelFiltersNoteIds && searchTextResults) {
2018-08-15 04:50:05 +08:00
results = searchTextResults.filter(item => labelFiltersNoteIds.includes(item.noteId));
}
else if (labelFiltersNoteIds) {
2018-06-06 07:12:52 +08:00
results = labelFiltersNoteIds.map(noteCacheService.getNotePath).filter(res => !!res);
}
else {
results = searchTextResults;
}
return results;
}
async function getFullTextResults(searchText) {
const tokens = searchText.toLowerCase().split(" ");
const tokenSql = ["1=1"];
for (const token of tokens) {
2019-02-16 04:21:26 +08:00
const safeToken = utils.sanitizeSql(token);
tokenSql.push(`(title LIKE '%${safeToken}%' OR content LIKE '%${safeToken}%')`);
}
const noteIds = await sql.getColumn(`
SELECT DISTINCT noteId
2019-02-16 04:21:26 +08:00
FROM
notes
JOIN note_contents USING(noteId)
WHERE isDeleted = 0
2019-02-16 04:21:26 +08:00
AND notes.isProtected = 0
2018-08-15 04:50:05 +08:00
AND type IN ('text', 'code')
AND ${tokenSql.join(' AND ')}`);
return noteIds;
}
async function saveSearchToNote(req) {
const noteContent = {
searchString: req.params.searchString
};
2018-06-06 07:12:52 +08:00
const {note} = await noteService.createNote('root', req.params.searchString, noteContent, {
json: true,
2018-03-26 11:25:17 +08:00
type: 'search',
mime: "application/json"
});
return { noteId: note.noteId };
}
module.exports = {
searchNotes,
saveSearchToNote
};