fulltext search now doesn't use FTS5, closes #489

This commit is contained in:
zadam 2019-04-21 11:54:13 +02:00
parent 36c6376220
commit 151641b659
2 changed files with 48 additions and 30 deletions

View File

@ -82,18 +82,8 @@ module.exports = function(filters, selectedColumns = 'notes.*') {
where += `${accessor} IS NULL`;
}
else if (filter.operator === '=' || filter.operator === '!=') {
if (filter.name === 'text') {
const safeSearchText = utils.sanitizeSql(filter.value);
const not = filter.operator.includes("!") ? "NOT" : "";
// fulltext needs to use subselect because fulltext doesn't support OR operations at all
// which makes it impossible to combine more operations together
where += `notes.noteId ${not} IN (SELECT noteId FROM note_fulltext WHERE note_fulltext MATCH '${safeSearchText}')`;
}
else {
where += `${accessor} ${filter.operator} ?`;
params.push(filter.value);
}
where += `${accessor} ${filter.operator} ?`;
params.push(filter.value);
}
else if (filter.operator === '*=' || filter.operator === '!*=') {
where += `${accessor}`
@ -106,9 +96,17 @@ module.exports = function(filters, selectedColumns = 'notes.*') {
+ ` LIKE ` + utils.prepareSqlForLike('', filter.value, '%');
}
else if (filter.operator === '*=*' || filter.operator === '!*=*') {
where += `${accessor}`
+ (filter.operator.includes('!') ? ' NOT' : '')
+ ` LIKE ` + utils.prepareSqlForLike('%', filter.value, '%');
const columns = filter.name === 'text' ? [getAccessor("title"), getAccessor("content")] : [accessor];
let condition = "(" + columns.map(column =>
`${column}` + ` LIKE ` + utils.prepareSqlForLike('%', filter.value, '%'))
.join(" OR ") + ")";
if (filter.operator.includes('!')) {
condition = "NOT(" + condition + ")";
}
where += condition;
}
else if ([">", ">=", "<", "<="].includes(filter.operator)) {
let floatParam;

View File

@ -43,25 +43,45 @@ function calculateSmartValue(v) {
}
module.exports = function (searchText) {
// if the string doesn't start with attribute then we consider it as just standard full text search
if (!searchText.trim().startsWith("@")) {
// replace with space instead of empty string since these characters are probably separators
const sanitizedSearchText = searchText.replace(/[^\w ]+/g, " ");
searchText = searchText.trim();
return [
{
// if the string doesn't start with attribute then we consider it as just standard full text search
if (!searchText.startsWith("@")) {
// replace with space instead of empty string since these characters are probably separators
const filters = [];
if (searchText.startsWith('"') && searchText.endsWith('"')) {
// "bla bla" will search for exact match
searchText = searchText.substr(1, searchText.length - 2);
filters.push({
relation: 'and',
name: 'text',
operator: '=',
value: sanitizedSearchText
},
{
relation: 'or',
name: 'noteId',
operator: '=',
value: sanitizedSearchText
operator: '*=*',
value: searchText
});
}
else {
const tokens = searchText.split(/\s+/);
for (const token of tokens) {
filters.push({
relation: 'and',
name: 'text',
operator: '*=*',
value: token
});
}
]
}
filters.push({
relation: 'or',
name: 'noteId',
operator: '=',
value: searchText
});
return filters;
}
const filters = [];