Skip to content

Commit

Permalink
Adding support for quoted search strings
Browse files Browse the repository at this point in the history
  • Loading branch information
mtlynch committed Jan 26, 2018
1 parent e7769ba commit ac8847e
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 1 deletion.
20 changes: 20 additions & 0 deletions src/app/_pipes/parse-search-query/parse-search-query.pipe.spec.ts
Expand Up @@ -36,6 +36,26 @@ describe('ParseSearchQueryPipe', () => {
expect(pipe.transform('ham cheese')).toEqual(new SearchParams(['ham', 'cheese'], []));
});

it('should ignore leading spaces', () => {
expect(pipe.transform(' ham cheese')).toEqual(new SearchParams(['ham', 'cheese'], []));
});

it('should ignore trailing spaces', () => {
expect(pipe.transform('ham cheese ')).toEqual(new SearchParams(['ham', 'cheese'], []));
});

it('should treat quoted strings as exact match', () => {
expect(pipe.transform('"sour cream" onions')).toEqual(new SearchParams(['sour cream', 'onions'], []));
});

it('should accept quoted entire query', () => {
expect(pipe.transform('"flourless chocolate cake"')).toEqual(new SearchParams(['flourless chocolate cake'], []));
});

it('should ignore unmatched double quote', () => {
expect(pipe.transform('"sour cream')).toEqual(new SearchParams(['sour', 'cream'], []));
});

it('should remove keywords when other keywords contain the substrings', () => {
expect(pipe.transform('chicken chick')).toEqual(new SearchParams(['chicken'], []));
});
Expand Down
31 changes: 30 additions & 1 deletion src/app/_pipes/parse-search-query/parse-search-query.pipe.ts
Expand Up @@ -29,7 +29,9 @@ export class ParseSearchQueryPipe implements PipeTransform {
const EXCLUDE_PREFIX = '-';

function tokenizeQuery(query: string) {
let tokens = query.toLowerCase().split(/[\s,]/).filter(x => x !== '');
let tokens = extractQuotedStrings(query);
const partialQuery = removeDoubleQuotes(removeQuotedStrings(query));
tokens = tokens.concat(extractTokens(partialQuery));

tokens = removeDuplicateTokens(tokens);

Expand All @@ -38,6 +40,33 @@ function tokenizeQuery(query: string) {
return tokens;
}

function extractQuotedStrings(query: string): string[] {
const quotedStrings : string[] = [];
let stringStart: number = -1;
for (let i = 0; i < query.length; i += 1) {
if (query[i] === '"') {
if (stringStart === -1) {
stringStart = i + 1;
} else {
quotedStrings.push(query.substr(stringStart, i - 1));
}
}
}
return quotedStrings;
}

function removeQuotedStrings(query: string): string {
return query.replace(/"[^"]*"/g, '').replace('"', '');
}

function removeDoubleQuotes(query: string): string {
return query.replace('"', '');
}

function extractTokens(query: string) : string[] {
return query.toLowerCase().split(/[\s,]/).filter(x => x !== '');
}

function removeSubstrings(tokens: string[]) {
const substrings = new Set();
// Find tokens that are contained in other tokens (e.g., "be" in "beef").
Expand Down

0 comments on commit ac8847e

Please sign in to comment.