Search indexes
Define search indexes in your schema to enable full-text search:string
The field to perform full-text search on. Must be a string field.
string[]
Additional fields to filter on using equality filters. These can be any Convex value type.
Querying with search
Use.withSearchIndex() to perform full-text search queries:
Search filter builder
TheSearchFilterBuilder is provided to construct search queries:
search
Search for terms in the indexed field:string
The name of the field to search in. Must match the index’s
searchField.string
The query text to search for.
- Returns results where any word of the query appears in the field
- Results are ranked by relevance considering:
- How many words in the query appear in the text?
- How many times do they appear?
- How long is the text field?
eq (equality filter)
Restrict search results to documents where a filter field equals a value:string
The name of the field to compare. Must be listed in the search index’s
filterFields.any
The value to compare against. Type must match the field type.
.eq() calls:
Search results
Search queries return documents in relevance order - the most relevant results appear first. The relevance algorithm considers:- Term frequency - How often query words appear in the document
- Document length - Shorter documents with matches rank higher
- Coverage - Documents matching more query words rank higher
Taking results
Use.take() to limit results:
Pagination
Search supports pagination for better performance:Common patterns
Search with category filter
Search with multiple filters
Search across multiple fields
Create separate indexes for different fields and combine results:Empty search query
Return all documents (filtered) when search query is empty:Search best practices
- Define indexes in schema - Search indexes must be defined in
convex/schema.tsbefore use. - Limit results with
.take()- Don’t use.collect()on search queries, as result sets can be large. - Use filter fields - Add
filterFieldsto search indexes for common filters like category or author. - Consider multiple indexes - Create separate search indexes for different fields (title, body, etc.).
- Results are already ordered - Search results come in relevance order, don’t apply additional
.order(). - Prefer search over
.filter()for text - Full-text search is much more efficient than filtering with string contains. - Handle empty queries - Decide whether empty search strings should return all results or none.
Limitations
- One search per query - You can only use
.withSearchIndex()once per query. To search multiple fields, run separate queries and combine results. - Equality filters only - Search indexes only support
.eq()filters, not range queries or other comparisons. - No ordering - Results are always in relevance order. You cannot apply
.order()to search results. - Filter fields must be in index - You can only filter on fields listed in the index’s
filterFieldsarray.
When to use search vs regular indexes
Use search indexes when:- Searching for words or phrases in text content
- You want relevance-ranked results
- Users type free-form search queries
- Filtering by exact values (IDs, enums, booleans)
- Range queries (dates, numbers)
- You need specific ordering (newest first, alphabetical)
- Querying structured data, not text content