Guides
Step-by-step tutorials and best practices for common LumoSearch use cases.
Browser Integration
Use LumoSearch in the browser with IndexedDB persistence
Web Worker Setup
Run search off the main thread for better performance
Persistence Strategies
Save and restore indexes with storage adapters
Semantic Reranking
Combine lexical and semantic search with hybrid reranking
Quick Recipes
Search with Filters
const results = search.search('javascript', {
limit: 10,
filters: {
category: 'tutorials',
published: true
},
predicate: (doc) => doc.rating > 4.0
})Incremental Updates
// Add new document
search.add({
title: 'New Article',
body: 'Content here...',
category: 'tutorials'
})
// Remove by index
search.removeAt(5)
// Remove by condition
search.remove((doc) => doc.archived === true)
// Replace entire collection
search.setCollection(newDocs)Highlighting Matches
const results = search.search('javascript patterns')
results.forEach(result => {
result.highlights.forEach(highlight => {
console.log('Field:', highlight.field)
console.log('Value:', highlight.value)
console.log('Match ranges:', highlight.indices)
// indices: [[0, 10], [25, 33]]
// Means: characters 0-10 and 25-33 matched
})
})Real-time Autocomplete
// As user types "jav"
const suggestions = search.autocomplete('jav', { limit: 5 })
// Returns documents where fields start with or contain "jav"
// ["JavaScript Patterns", "Java Tutorial", ...]Nested Field Search
const docs = [
{
title: 'Article',
author: {
name: 'Jane Doe',
bio: 'Software engineer'
}
}
]
const search = new LumoSearch(docs, {
keys: [
{ name: 'title', weight: 3 },
{ name: 'author.name', weight: 2 },
{ name: 'author.bio', weight: 1 }
]
})Synonym Configuration
const search = new LumoSearch(docs, {
keys: ['title', 'body'],
synonyms: {
js: ['javascript'],
ts: ['typescript'],
auth: ['authentication', 'authorization'],
ml: ['machine learning', 'machinelearning']
}
})
// Query "js auth" will match documents containing:
// - "javascript authentication"
// - "javascript authorization"
// etc.Performance Tuning
const search = new LumoSearch(docs, {
keys: ['title', 'body'],
// Increase for better recall (slower)
candidateLimit: 500,
// Decrease for faster queries (less recall)
candidateLimit: 100,
// Balance: 250 (default)
candidateLimit: 250
})
// candidateLimit affects the tradeoff between:
// - Speed: fewer candidates = faster
// - Recall: more candidates = better resultsCommon Patterns
E-commerce Product Search
const products = [
{
name: 'Wireless Headphones',
description: 'Noise-cancelling over-ear headphones',
brand: 'AudioTech',
category: 'Electronics',
price: 299.99,
inStock: true
}
]
const search = new LumoSearch(products, {
keys: [
{ name: 'name', weight: 3 },
{ name: 'brand', weight: 2 },
{ name: 'description', weight: 1 }
]
})
// Search with filters
const results = search.search('wireless headphones', {
filters: {
category: 'Electronics',
inStock: true
},
predicate: (p) => p.price < 500
})Documentation Search
const docs = [
{
title: 'Getting Started',
content: 'Introduction to the library...',
section: 'guide',
tags: ['beginner', 'setup']
}
]
const search = new LumoSearch(docs, {
keys: [
{ name: 'title', weight: 5 },
{ name: 'tags', weight: 3 },
{ name: 'content', weight: 1 }
],
synonyms: {
intro: ['introduction', 'getting started'],
config: ['configuration', 'setup']
}
})Blog Search
const posts = [
{
title: 'Understanding React Hooks',
excerpt: 'A deep dive into useState and useEffect...',
author: 'Jane Doe',
tags: ['react', 'hooks', 'javascript'],
publishedAt: '2024-01-15'
}
]
const search = new LumoSearch(posts, {
keys: [
{ name: 'title', weight: 4 },
{ name: 'tags', weight: 3 },
{ name: 'author', weight: 2 },
{ name: 'excerpt', weight: 1 }
]
})
// Filter by date
const results = search.search('react hooks', {
predicate: (post) => {
const date = new Date(post.publishedAt)
const monthAgo = new Date()
monthAgo.setMonth(monthAgo.getMonth() - 1)
return date > monthAgo
}
})