allow combining tokens in text and title/attributes, fixes #2820

This commit is contained in:
zadam 2022-04-29 22:59:00 +02:00
parent 70edd9a210
commit f705c432fd
3 changed files with 32 additions and 10 deletions

View File

@ -10,7 +10,7 @@ const utils = require("../../utils");
// FIXME: create common subclass with NoteContentUnprotectedFulltextExp to avoid duplication // FIXME: create common subclass with NoteContentUnprotectedFulltextExp to avoid duplication
class NoteContentProtectedFulltextExp extends Expression { class NoteContentProtectedFulltextExp extends Expression {
constructor(operator, tokens, raw) { constructor(operator, {tokens, raw, flatText}) {
super(); super();
if (operator !== '*=*') { if (operator !== '*=*') {
@ -19,6 +19,7 @@ class NoteContentProtectedFulltextExp extends Expression {
this.tokens = tokens; this.tokens = tokens;
this.raw = !!raw; this.raw = !!raw;
this.flatText = !!flatText;
} }
execute(inputNoteSet) { execute(inputNoteSet) {
@ -49,7 +50,17 @@ class NoteContentProtectedFulltextExp extends Expression {
content = this.preprocessContent(content, type, mime); content = this.preprocessContent(content, type, mime);
if (!this.tokens.find(token => !content.includes(token))) { const nonMatchingToken = this.tokens.find(token =>
!content.includes(token) &&
(
// in case of default fulltext search we should consider both title, attrs and content
// so e.g. "hello world" should match when "hello" is in title and "world" in content
!this.flatText
|| !becca.notes[noteId].getFlatText().includes(token)
)
);
if (!nonMatchingToken) {
resultNoteSet.add(becca.notes[noteId]); resultNoteSet.add(becca.notes[noteId]);
} }
} }

View File

@ -8,7 +8,7 @@ const utils = require("../../utils");
// FIXME: create common subclass with NoteContentProtectedFulltextExp to avoid duplication // FIXME: create common subclass with NoteContentProtectedFulltextExp to avoid duplication
class NoteContentUnprotectedFulltextExp extends Expression { class NoteContentUnprotectedFulltextExp extends Expression {
constructor(operator, tokens, raw) { constructor(operator, {tokens, raw, flatText}) {
super(); super();
if (operator !== '*=*') { if (operator !== '*=*') {
@ -17,6 +17,7 @@ class NoteContentUnprotectedFulltextExp extends Expression {
this.tokens = tokens; this.tokens = tokens;
this.raw = !!raw; this.raw = !!raw;
this.flatText = !!flatText;
} }
execute(inputNoteSet) { execute(inputNoteSet) {
@ -35,7 +36,17 @@ class NoteContentUnprotectedFulltextExp extends Expression {
content = this.preprocessContent(content, type, mime); content = this.preprocessContent(content, type, mime);
if (!this.tokens.find(token => !content.includes(token))) { const nonMatchingToken = this.tokens.find(token =>
!content.includes(token) &&
(
// in case of default fulltext search we should consider both title, attrs and content
// so e.g. "hello world" should match when "hello" is in title and "world" in content
!this.flatText
|| !becca.notes[noteId].getFlatText().includes(token)
)
);
if (!nonMatchingToken) {
resultNoteSet.add(becca.notes[noteId]); resultNoteSet.add(becca.notes[noteId]);
} }
} }

View File

@ -32,8 +32,8 @@ function getFulltext(tokens, searchContext) {
if (!searchContext.fastSearch) { if (!searchContext.fastSearch) {
return new OrExp([ return new OrExp([
new NoteFlatTextExp(tokens), new NoteFlatTextExp(tokens),
new NoteContentProtectedFulltextExp('*=*', tokens), new NoteContentProtectedFulltextExp('*=*', {tokens, flatText: true}),
new NoteContentUnprotectedFulltextExp('*=*', tokens) new NoteContentUnprotectedFulltextExp('*=*', {tokens, flatText: true})
]); ]);
} }
else { else {
@ -141,8 +141,8 @@ function getExpression(tokens, searchContext, level = 0) {
i++; i++;
return new OrExp([ return new OrExp([
new NoteContentUnprotectedFulltextExp(operator, [tokens[i].token], raw), new NoteContentUnprotectedFulltextExp(operator, {tokens: [tokens[i].token], raw }),
new NoteContentProtectedFulltextExp(operator, [tokens[i].token], raw) new NoteContentProtectedFulltextExp(operator, {tokens: [tokens[i].token], raw })
]); ]);
} }
@ -196,8 +196,8 @@ function getExpression(tokens, searchContext, level = 0) {
return new OrExp([ return new OrExp([
new PropertyComparisonExp(searchContext, 'title', '*=*', tokens[i].token), new PropertyComparisonExp(searchContext, 'title', '*=*', tokens[i].token),
new NoteContentProtectedFulltextExp('*=*', [tokens[i].token]), new NoteContentProtectedFulltextExp('*=*', {tokens: [tokens[i].token]}),
new NoteContentUnprotectedFulltextExp('*=*', [tokens[i].token]) new NoteContentUnprotectedFulltextExp('*=*', {tokens: [tokens[i].token]})
]); ]);
} }