Search Engine
Fast and lightweight search engine for Dart/Flutter with fuzzy search capabilities β lightweight and flexible.
π Live Demo:** View on GitHub Pages
How Search Works
The search engine uses a 4-level priority algorithm to find the most relevant results:
1. Search Priorities (in order of importance)
- Exact matches -
"apple"
="apple"
- Starts with -
"app"
β"apple"
- Contains -
"ple"
β"apple"
- Fuzzy search -
"aple"
β"apple"
(only for queries β₯3 characters)
2. Search Fields
By default, search looks in 3 fields:
name
- item namesubtitle
- item subtitlesearchData
- additional search data
3. Character Types
Search works with any characters:
- β
Letters:
"apple"
,"Π―Π±Π»ΠΎΠΊΠΎ"
- β
Numbers:
"iPhone 14"
,"Windows 11"
- β
Special characters:
"C++"
,"React.js"
- β
Emojis:
"π Apple"
- β
Spaces:
"Red fruit"
4. Why 4 Levels?
This is one smart algorithm, not 4 different searches:
- Exact - for quick exact match finding (100% relevance)
- Starts with - for autocomplete (user types beginning) (90% relevance)
- Contains - for partial word search (70% relevance)
- Fuzzy - for typo correction (50% relevance)
Results are sorted by priority - exact matches first, then others.
Features
- π Fast search by name, subtitle, or custom fields
- π― Fuzzy search for typos and misspellings
- β‘ Optimized performance with priority-based results
- π¨ Configurable search behavior
- π¦ Zero dependencies - pure Dart implementation
Installation
Add this to your package's pubspec.yaml
file:
dependencies:
fuzzy_search_engine: ^1.0.1
Quick Start
import 'package:fuzzy_search_engine/fuzzy_search_engine.dart';
void main() {
final items = [
SearchableItem(id: '1', name: 'Apple', subtitle: 'Red fruit'),
SearchableItem(id: '2', name: 'Banana', subtitle: 'Yellow fruit'),
SearchableItem(id: '3', name: 'Orange', subtitle: 'Orange fruit'),
];
// Basic search
final results = SearchEngine.search(items, 'apple');
print(results); // [Apple]
// Fuzzy search for typos
final fuzzyResults = SearchEngine.fuzzySearch(items, 'aple');
print(fuzzyResults); // [Apple]
}
API Reference
SearchableItem
Represents a searchable item with customizable fields.
const item = SearchableItem(
id: '1',
name: 'Apple',
icon: 'π',
subtitle: 'Red fruit',
searchData: 'apple fruit red',
data: {'price': 1.99},
);
SearchEngine
Main search engine class with static methods.
Basic Search
// Search with default configuration
List<SearchableItem> results = SearchEngine.search(items, query);
// Search with custom configuration
List<SearchableItem> results = SearchEngine.search(
items,
query,
config: SearchConfig(
searchFields: ['name', 'subtitle'],
caseSensitive: false,
// You can enable debug logs in Flutter apps using debugPrint
// debugLogger: debugPrint,
),
);
Fuzzy Search
// Fuzzy search for typos and misspellings
List<SearchableItem> results = SearchEngine.fuzzySearch(items, query);
// Fuzzy search with custom configuration
List<SearchableItem> results = SearchEngine.fuzzySearch(
items,
query,
config: SearchConfig(
fuzzyEnabled: true,
maxFuzzyDistance: 3,
// debugLogger: debugPrint,
),
);
Utility Methods
// Sort items by name
List<SearchableItem> sorted = SearchEngine.getSortedItems(items);
// Find item by ID
SearchableItem? item = SearchEngine.getItemById(items, 'item_id');
SearchConfig
Configuration for search behavior.
const config = SearchConfig(
searchFields: ['name', 'subtitle', 'searchData'], // Fields to search in
fuzzyEnabled: true, // Enable fuzzy search
maxFuzzyDistance: 3, // Max distance for fuzzy search
caseSensitive: false, // Case sensitive search
);
Search Algorithm
The search engine uses a priority-based algorithm:
- Exact matches - Highest priority
- Starts with matches - Second priority
- Contains matches - Third priority
- Fuzzy matches - Lowest priority (only in fuzzy search)
Fuzzy Search
Fuzzy search uses the Levenshtein distance algorithm to find items with typos and misspellings. It automatically adjusts the distance threshold based on query length for optimal results.
Examples
Basic Usage
final countries = [
SearchableItem(id: 'us', name: 'United States', subtitle: 'North America'),
SearchableItem(id: 'uk', name: 'United Kingdom', subtitle: 'Europe'),
SearchableItem(id: 'ca', name: 'Canada', subtitle: 'North America'),
];
// Search by name
final results = SearchEngine.search(countries, 'united');
// Returns: [United States, United Kingdom]
// Search by subtitle
final results = SearchEngine.search(countries, 'europe');
// Returns: [United Kingdom]
Advanced Configuration
final config = SearchConfig(
searchFields: ['name'], // Only search in name field
caseSensitive: true, // Case sensitive search
fuzzyEnabled: false, // Disable fuzzy search
);
final results = SearchEngine.search(countries, 'UNITED', config: config);
// Returns: [] (no exact match for 'UNITED')
Fuzzy Search Examples
final fruits = [
SearchableItem(id: '1', name: 'Apple'),
SearchableItem(id: '2', name: 'Banana'),
SearchableItem(id: '3', name: 'Orange'),
];
// Find items with typos
SearchEngine.fuzzySearch(fruits, 'aple'); // Returns: [Apple]
SearchEngine.fuzzySearch(fruits, 'bananna'); // Returns: [Banana]
SearchEngine.fuzzySearch(fruits, 'oragne'); // Returns: [Orange]
Performance
- Time Complexity: O(n * m) where n is number of items, m is average field length
- Space Complexity: O(n) for storing results
- Memory: Minimal memory footprint with no external dependencies
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
License
This project is licensed under the MIT License.
Libraries
- fuzzy_search_engine
- A Dart package for fast and lightweight search with fuzzy search capabilities.