Full Text Search
This doc is about full-text search capabilities. For vector similarity search and semantic search, see the Vector Embeddings documentation.
Full-Text Search
Full-Text Search allows you to search text content efficiently.
Enabling FTS
Create a collection with FTS support:
await client.settings.collections.create({
name: "articles",
type: "base",
fields: [
{ name: "title", type: "text", required: true },
{ name: "content", type: "text", required: true },
{ name: "tags", type: "json" },
],
indexes: [
{
name: "articles_fts",
type: "fts",
fields: ["title", "content"],
},
],
});
Note: The above example shows creating FTS indexes via the indexes
property during collection creation. While the search functionality is confirmed
to work, the exact mechanism for configuring FTS indexes may need verification
with the latest backend implementation.
Basic Search
// Search for articles containing "react"
const results = await client.collection("articles").search("react");
console.log(results);
// [
// { id: "1", title: "React Tutorial", content: "...", ... },
// { id: "2", title: "Building React Apps", content: "...", ... },
// ]
Advanced Search Queries
VSKI supports FTS5 query syntax:
Phrase Search
// Search for exact phrase
const results = await client.collection("articles").search('"react hooks"');
OR Queries
// Search for articles containing react OR vue
const results = await client.collection("articles").search("react OR vue");
AND Queries
// Search for articles containing both react AND hooks
const results = await client.collection("articles").search("react hooks");
NOT Queries
// Search for articles containing "react" but not "angular"
const results = await client.collection("articles").search("react NOT angular");
Wildcard Searches
// Search for words starting with "react"
const results = await client.collection("articles").search("react*");
Proximity Search
// Search for words within 5 words of each other
const results = await client.collection("articles").search(
'"react hooks" NEAR/5 "components"',
);
Search with Filters
Combine search with regular filters:
const results = await client.collection("articles").getList(1, 20, {
filter: "published = true",
search: "react tutorial",
});
Search Options
const results = await client.collection("articles").search("react", {
fields: ["title", "content"], // Search specific fields
limit: 10, // Limit results
expand: "author", // Expand relations
});
Search Result Ranking
Relevance Scoring
FTS provides relevance scores:
const results = await client.collection("articles").search("react");
results.forEach((result) => {
console.log(`${result.title} - Score: ${result._rank}`);
});
Custom Ranking
Combine search with custom scoring:
const results = await client.collection("articles").getList(1, 20, {
search: "react",
sort: "views", // Sort by most viewed
});
Search Suggestions
Implement autocomplete suggestions:
async function getSuggestions(query: string) {
if (query.length < 2) return [];
const results = await client.collection("articles").getList(1, 5, {
search: `${query}*`, // Prefix search
fields: "title",
});
return results.items.map((item) => item.title);
}
Search Analytics
Track search queries for analytics:
async function logSearch(query: string, userId?: string) {
await client.collection("search_logs").create({
query,
userId,
timestamp: new Date().toISOString(),
resultsCount: results.items.length,
});
}
// Usage
const results = await client.collection("articles").search(query);
await logSearch(query, currentUserId);
Performance Optimization
Indexing
Create appropriate indexes for search:
await client.settings.collections.create({
name: "products",
type: "base",
fields: [
{ name: "name", type: "text", required: true },
{ name: "description", type: "text" },
{ name: "category", type: "text" },
],
indexes: [
{
name: "products_fts",
type: "fts",
fields: ["name", "description"],
},
{
name: "products_category",
type: "index",
fields: ["category"],
},
],
});
Caching
Cache search results:
const searchCache = new Map();
async function cachedSearch(query: string) {
if (searchCache.has(query)) {
return searchCache.get(query);
}
const results = await client.collection("articles").search(query);
searchCache.set(query, results);
return results;
}
Debouncing
Debounce search input:
let searchTimeout: number;
function debounceSearch(query: string) {
clearTimeout(searchTimeout);
searchTimeout = setTimeout(async () => {
const results = await client.collection("articles").search(query);
displayResults(results);
}, 300);
}
Practical Examples
E-commerce Product Search
// Search products with filters
async function searchProducts(
query: string,
category?: string,
minPrice?: number,
) {
let filter = "published = true";
if (category) {
filter += ` && category = '${category}'`;
}
if (minPrice) {
filter += ` && price >= ${minPrice}`;
}
return await client.collection("products").getList(1, 20, {
filter,
search: query,
sort: "-popularity",
});
}
FAQ Search
// FAQ search with relevance ranking
async function searchFAQ(query: string) {
const results = await client.collection("faqs").search(query, {
fields: ["question", "answer"],
limit: 5,
});
return results;
}
API Endpoints
| Method | Endpoint | Description |
|---|---|---|
GET |
/api/collections/:name/records/search |
Full-text search |
GET |
/api/collections/:name/records |
List with search parameter |
Best Practices
- Use appropriate indexing - Create FTS indexes for searchable fields
- Optimize query syntax - Use specific queries instead of broad ones
- Implement pagination - Always use limits with search results
- Cache popular searches - Reduce server load
- Monitor search performance - Track slow queries
- Normalize text - Consistent text formatting improves search