mk_smart_search 1.0.0
mk_smart_search: ^1.0.0 copied to clipboard
High-performance bilingual (English/Arabic) fuzzy search engine for Flutter. Features intelligent typo tolerance, semantic matching, field weighting, and automatic isolate optimization for large datas [...]
Smart Search 🔍 #
A powerful bilingual (English/Arabic) fuzzy search engine for Flutter with typo tolerance, advanced matching algorithms, and performance optimizations.
Features #
- 🌍 Bilingual Support: Handles both English and Arabic text with proper normalization
- ✨ Typo Tolerance: Automatically generates typo variants for better matching
- 🎯 Fuzzy Matching: Uses Damerau-Levenshtein distance and N-gram similarity
- ⚡ Performance: LRU caching and isolate support for large datasets
- 🎨 Smart Scoring: Phrase matching, word order bonuses, field weighting
- 🔧 Easy Integration: Extension methods for seamless List
- 🐛 Debug Mode: Comprehensive debug output for development
Getting Started #
Installation #
Add mk_smart_search to your pubspec.yaml:
dependencies:
mk_smart_search: ^1.0.0
Then run:
flutter pub get
Basic Usage #
import 'package:mk_smart_search/mk_smart_search.dart';
// Your data model
class Product {
final String nameEn;
final String nameAr;
final String category;
Map<String, dynamic> toJson() => {
'nameEn': nameEn,
'nameAr': nameAr,
'category': category,
};
}
// Search your list
final products = [Product(...), Product(...), ...];
final results = await products.smartSearchExtension(
query: 'samsung galaxy',
searchFieldsMap: {
'name': ['nameEn', 'nameAr'],
'category': ['category'],
},
toJson: (p) => p.toJson(),
fieldWeights: {
'name': 3.0, // Name matches are 3x more important
'category': 0.5, // Category matches are less important
},
minScore: 0.4, // Minimum relevance score (0.0-1.0)
limit: 10, // Maximum number of results
);
Advanced Usage #
Search with Scores #
Get results with relevance scores:
final results = await products.smartSearchWithScores<Product>(
query: 'samsung',
searchFieldsMap: {'name': ['nameEn']},
toJson: (p) => p.toJson(),
);
for (final result in results) {
print('${result.item.nameEn}: ${result.score}');
}
Debug Mode #
Enable debug output to see detailed search analysis:
final results = await products.smartSearchExtension(
query: 'samsung',
searchFieldsMap: {'name': ['nameEn']},
toJson: (p) => p.toJson(),
debug: true, // Enable debug output
);
Performance Optimization #
For large datasets (>1000 items), the package automatically uses isolates:
final results = await products.smartSearchExtension(
query: 'samsung',
searchFieldsMap: {'name': ['nameEn']},
toJson: (p) => p.toJson(),
useIsolate: true, // Default: true, uses isolate for >1000 items
);
Fast Search (No Debug Overhead) #
For maximum performance without debug capabilities:
final results = await products.fastSearchExtension<Product>(
query: 'samsung',
searchFieldsMap: {'name': ['nameEn']},
toJson: (p) => p.toJson(),
);
How It Works #
Typo Variant Generation #
The search engine automatically generates typo variants for each query word:
- English: Character transpositions, common letter substitutions (j/h, p/ph), deletions
- Arabic: Character variants (أ/إ/آ → ا), diacritic handling, transpositions
Scoring Algorithm #
The search uses a multi-stage scoring approach:
- Exact match → 1.0
- Prefix match → 0.90-1.0 (ratio-based)
- Fuzzy prefix → 0.85+ (for typos at end)
- Substring match → 0.40-0.85 (position-penalized)
- Edit distance → Calculated from Damerau-Levenshtein/Levenshtein
- N-gram similarity → Weighted combination
Semantic Relevance #
The engine includes semantic relevance checks to prevent false matches (e.g., "pjone" won't match "canon" despite similar edit distance).
API Reference #
Extension Methods #
smartSearchExtension<T>
Main search method with full feature support.
Future<List<T>> smartSearchExtension({
required String query,
required Map<String, List<String>> searchFieldsMap,
required Map<String, dynamic> Function(T) toJson,
Map<String, double> fieldWeights = const {},
double minScore = 0.3,
int limit = 10,
bool useDamerauLevenshtein = true,
bool useNGram = true,
bool useIsolate = true,
bool debug = false,
})
smartSearchWithScores<T>
Returns results with relevance scores.
Future<List<SmartSearchResult<T>>> smartSearchWithScores({
required String query,
required Map<String, List<String>> searchFieldsMap,
required Map<String, dynamic> Function(T) toJson,
Map<String, double> fieldWeights = const {},
double minScore = 0.3,
int limit = 10,
bool useDamerauLevenshtein = true,
bool useNGram = true,
bool useIsolate = true,
bool debug = false,
})
fastSearchExtension<T>
Fast search without debug overhead.
Future<List<T>> fastSearchExtension({
required String query,
required Map<String, List<String>> searchFieldsMap,
required Map<String, dynamic> Function(T) toJson,
Map<String, double> fieldWeights = const {},
double minScore = 0.3,
int limit = 10,
bool useIsolate = true,
bool useDamerauLevenshtein = true,
bool useNGram = true,
})
Core Classes #
EnhancedSmartSearch
Core search engine with static methods:
similarityScore()- Calculate similarity between two stringsitemScore()- Calculate relevance score for an itemgroupQueryWordsByOriginal()- Generate typo variantssplitWords()- Normalize and split text into wordsclearCaches()- Clear internal cachesgetCacheStats()- Get cache statistics
SmartSearchResult<T>
Search result containing item and score:
class SmartSearchResult<T> {
final T item;
final double score; // 0.0 to 1.0
}
Examples #
See the /example folder for a complete working example.
Performance #
- Caching: LRU caches for normalized text, word splits, typo variants, and similarity scores
- Isolates: Automatic isolate usage for datasets >1000 items
- Optimizations: Early exits, length-based filtering, semantic relevance checks
Contributing #
Contributions are welcome! Please feel free to submit a Pull Request.
License #
This project is licensed under the MIT License - see the LICENSE file for details.
About the Author #
Mohamed Khaled Khira
Senior Mobile Developer | Flutter & Dart Specialist
- 🌐 Portfolio: mkhira.github.io/MyPortfolio
- 💼 LinkedIn: linkedin.com/in/mohamed-khaled-058719197
- 📧 Contact: +966550493860