Implementing Search Functionality
1. Defining Search Fields
Example: Search query field
type Query {
search(query: String!, types: [SearchType!], first: Int = 20): SearchConnection!
}
union SearchHit = User | Post | Product
2. Using Search Arguments
| Argument | Use |
|---|---|
| query | User-entered text |
| types | Restrict result kinds |
| filter | Domain filters (date range, tags) |
| first / after | Pagination |
3. Implementing Full-text Search
| Backend | Tool |
|---|---|
| Postgres | tsvector + GIN index |
| MySQL | MATCH ... AGAINST |
| External | Elasticsearch, Meilisearch, Typesense, Algolia |
4. Implementing Fuzzy Search
| Method | Detail |
|---|---|
| Trigram | pg_trgm similarity |
| Levenshtein | Edit distance |
| Search engine | Built-in fuzziness param |
5. Using Search Operators
| Operator | Example |
|---|---|
| AND/OR | graphql AND apollo |
| Phrase | "exact phrase" |
| Exclude | -spam |
| Field | title:graphql |
6. Implementing Search Filters
Example: Faceted search
input SearchFilter {
types: [SearchType!]
authorId: ID
dateRange: DateFilter
tags: [String!]
}
7. Implementing Search Sorting
| Sort | Use |
|---|---|
| RELEVANCE | Default; from search engine score |
| RECENT | By createdAt DESC |
| POPULAR | By interaction count |
8. Highlighting Search Results
Example: Highlight field
type SearchHit {
node: Post!
score: Float!
highlights: [Highlight!]!
}
type Highlight { field: String!, snippet: String! }
9. Implementing Search Pagination
| Approach | Detail |
|---|---|
| Cursor | Encode score + tiebreaker id |
| search_after (ES) | Native deep pagination |
| Hard cap | Limit max page (e.g. 1000 results) |
10. Optimizing Search Performance
| Optimization | Detail |
|---|---|
| Cache common queries | Redis, edge cache |
| Prefix index for autocomplete | Edge n-grams |
| Async indexing | Outbox + queue |
| Limit returned fields | Avoid loading full docs |