Skip to content

Commit 5941363

Browse files
authored
Add support for partial term matches in search (#444)
* Add support for partial term matches in search * Simplify * Update unit tests to handle updated search logic * Added custom function for search query that handles partials * Fix some typos * Oops, deleted too much * Search for links as you type
1 parent e30ddb8 commit 5941363

File tree

4 files changed

+41
-8
lines changed

4 files changed

+41
-8
lines changed

db/driver-postgres.go

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,13 @@ type postgresRecipeDriverAdapter struct{}
3030
func (postgresRecipeDriverAdapter) GetSearchFields(filterFields []models.SearchField, query string) (string, []any) {
3131
fieldStr := ""
3232
fieldArgs := make([]any, 0)
33-
for _, field := range supportedSearchFields {
34-
if lo.Contains(filterFields, field) {
35-
if fieldStr != "" {
36-
fieldStr += " OR "
37-
}
38-
fieldStr += fmt.Sprintf("to_tsvector('english', r.%s) @@ plainto_tsquery('english', ?)", field)
39-
fieldArgs = append(fieldArgs, query)
33+
34+
for _, field := range lo.Intersect(filterFields, supportedSearchFields[:]) {
35+
if fieldStr != "" {
36+
fieldStr += " OR "
4037
}
38+
fieldStr += fmt.Sprintf("to_tsvector('english', r.%s) @@ websearch_to_wildcard_tsquery('english', ?)", field)
39+
fieldArgs = append(fieldArgs, query)
4140
}
4241

4342
return fieldStr, fieldArgs
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
BEGIN;
2+
3+
DROP FUNCTION IF EXISTS websearch_to_wildcard_tsquery(config regconfig, querytext text);
4+
5+
COMMIT;
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
BEGIN;
2+
3+
CREATE OR REPLACE FUNCTION websearch_to_wildcard_tsquery(config regconfig, querytext text)
4+
RETURNS tsquery AS $$
5+
DECLARE
6+
query_splits text[];
7+
split text;
8+
new_querytext text := '';
9+
BEGIN
10+
SELECT regexp_split_to_array(d::text, '\s* \s*') INTO query_splits FROM websearch_to_tsquery(config, querytext) d;
11+
FOREACH split IN ARRAY query_splits LOOP
12+
CASE WHEN split = '|' OR split = '&' OR split = '!' OR split = '<->' OR split = '!(' OR split = ')'
13+
THEN new_querytext := new_querytext || split || ' ';
14+
ELSE new_querytext := new_querytext || split || ':* ';
15+
END CASE;
16+
END LOOP;
17+
RETURN to_tsquery(config, new_querytext);
18+
END;
19+
$$ LANGUAGE plpgsql;
20+
21+
COMMIT;

static/src/components/recipe-link-editor/recipe-link-editor.tsx

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,8 @@ export class RecipeLinkEditor {
4545
autocorrect="on"
4646
spellcheck
4747
autofocus
48-
onIonBlur={e => this.query = e.target.value as string}
48+
debounce={500}
49+
onIonInput={e => this.query = e.target.value as string}
4950
ref={el => this.searchInput = el} />
5051
</ion-item>
5152
<ion-content>
@@ -78,6 +79,13 @@ export class RecipeLinkEditor {
7879
@Watch('query')
7980
@Watch('includeArchived')
8081
async onSearchInputChanged() {
82+
// Require at least 2 characters to search
83+
if (isNullOrEmpty(this.query) || this.query.length < 2) {
84+
this.matchingRecipes = [];
85+
this.selectedRecipeId = null;
86+
return;
87+
}
88+
8189
let states: RecipeState[] = [RecipeState.Active];
8290
if (this.includeArchived) {
8391
states = [...states, RecipeState.Archived];

0 commit comments

Comments
 (0)