1
0
mirror of https://github.com/xuthus83/pigallery2.git synced 2024-11-03 21:04:03 +08:00

Making "and" to be the default operator for search queries #309

This commit is contained in:
Patrik J. Braun 2021-05-23 18:05:12 +02:00
parent f84f555182
commit f6aaa6de58
2 changed files with 19 additions and 8 deletions

View File

@ -85,7 +85,7 @@ export class SearchQueryParser {
return Date.parse(text); return Date.parse(text);
} }
public parse(str: string, implicitOR = true): SearchQueryDTO { public parse(str: string, implicitAND = true): SearchQueryDTO {
str = str.replace(/\s\s+/g, ' ') // remove double spaces str = str.replace(/\s\s+/g, ' ') // remove double spaces
.replace(/:\s+/g, ':').replace(/\)(?=\S)/g, ') ').trim(); .replace(/:\s+/g, ':').replace(/\)(?=\S)/g, ') ').trim();
@ -123,25 +123,25 @@ export class SearchQueryParser {
if (tokenEnd !== str.length - 1) { if (tokenEnd !== str.length - 1) {
if (str.startsWith(' ' + this.keywords.and, tokenEnd)) { if (str.startsWith(' ' + this.keywords.and, tokenEnd)) {
const rest = this.parse(str.slice(tokenEnd + (' ' + this.keywords.and).length), implicitOR); const rest = this.parse(str.slice(tokenEnd + (' ' + this.keywords.and).length), implicitAND);
return { return {
type: SearchQueryTypes.AND, type: SearchQueryTypes.AND,
list: [this.parse(str.slice(0, tokenEnd), implicitOR), // trim brackets list: [this.parse(str.slice(0, tokenEnd), implicitAND), // trim brackets
...(rest.type === SearchQueryTypes.AND ? (rest as SearchListQuery).list : [rest])] ...(rest.type === SearchQueryTypes.AND ? (rest as SearchListQuery).list : [rest])]
} as ANDSearchQuery; } as ANDSearchQuery;
} else if (str.startsWith(' ' + this.keywords.or, tokenEnd)) { } else if (str.startsWith(' ' + this.keywords.or, tokenEnd)) {
const rest = this.parse(str.slice(tokenEnd + (' ' + this.keywords.or).length), implicitOR); const rest = this.parse(str.slice(tokenEnd + (' ' + this.keywords.or).length), implicitAND);
return { return {
type: SearchQueryTypes.OR, type: SearchQueryTypes.OR,
list: [this.parse(str.slice(0, tokenEnd), implicitOR), // trim brackets list: [this.parse(str.slice(0, tokenEnd), implicitAND), // trim brackets
...(rest.type === SearchQueryTypes.OR ? (rest as SearchListQuery).list : [rest])] ...(rest.type === SearchQueryTypes.OR ? (rest as SearchListQuery).list : [rest])]
} as ORSearchQuery; } as ORSearchQuery;
} else { // Relation cannot be detected } else { // Relation cannot be detected
const t = implicitOR === true ? SearchQueryTypes.OR : SearchQueryTypes.UNKNOWN_RELATION; const t = implicitAND === true ? SearchQueryTypes.AND : SearchQueryTypes.UNKNOWN_RELATION;
const rest = this.parse(str.slice(tokenEnd), implicitOR); const rest = this.parse(str.slice(tokenEnd), implicitAND);
return { return {
type: t, type: t,
list: [this.parse(str.slice(0, tokenEnd), implicitOR), // trim brackets list: [this.parse(str.slice(0, tokenEnd), implicitAND), // trim brackets
...(rest.type === t ? (rest as SearchListQuery).list : [rest])] ...(rest.type === t ? (rest as SearchListQuery).list : [rest])]
} as SearchListQuery; } as SearchListQuery;
} }

View File

@ -116,6 +116,17 @@ describe('SearchQueryParser', () => {
check({type: SearchQueryTypes.orientation, landscape: true} as OrientationSearch); check({type: SearchQueryTypes.orientation, landscape: true} as OrientationSearch);
check({type: SearchQueryTypes.orientation, landscape: false} as OrientationSearch); check({type: SearchQueryTypes.orientation, landscape: false} as OrientationSearch);
}); });
it('Default logical operator should be AND', () => {
const parser = new SearchQueryParser(queryKeywords);
expect(parser.parse('a b')).to.deep.equals({
type: SearchQueryTypes.AND,
list: [
{type: SearchQueryTypes.any_text, text: 'a'} as TextSearch,
{type: SearchQueryTypes.any_text, text: 'b'} as TextSearch
]
} as ANDSearchQuery);
});
it('And search', () => { it('And search', () => {
check({ check({
type: SearchQueryTypes.AND, type: SearchQueryTypes.AND,