smartSearchWithScores method
Future<List<SmartSearchResult<T> > >
smartSearchWithScores({
- required String query,
- required Map<
String, List< searchFieldsMap,String> > - required Map<
String, dynamic> toJson(- T
- Map<
String, double> fieldWeights = const {}, - double minScore = 0.3,
- int limit = 10,
- bool useDamerauLevenshtein = true,
- bool useNGram = true,
- bool useIsolate = true,
- bool debug = false,
Performs search and returns results with scores.
Returns SmartSearchResult objects that include both the item and its score, useful when you need to display or filter by relevance scores.
Note: This recalculates scores after filtering, so it's slightly less efficient than smartSearchDynamicDetailedExtension but provides score access.
See smartSearchDynamicDetailedExtension for parameter documentation.
Example:
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}');
}
Implementation
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,
}) async {
// Get items first
final items = await smartSearchDynamicDetailedExtension(
query: query,
searchFieldsMap: searchFieldsMap,
toJson: toJson,
fieldWeights: fieldWeights,
minScore: minScore,
limit: limit,
useDamerauLevenshtein: useDamerauLevenshtein,
useNGram: useNGram,
useIsolate: useIsolate,
debug: false, // Disable debug to avoid duplicate output
);
// Recalculate scores for SearchResult objects
final queryWordGroups = EnhancedSmartSearch.groupQueryWordsByOriginal(query);
final results = <SmartSearchResult<T>>[];
for (final item in items) {
final itemJson = toJson(item);
double totalScore = 0.0;
double totalWeight = 0.0;
searchFieldsMap.forEach((fieldName, subFields) {
final weight = fieldWeights[fieldName] ?? 1.0;
final fieldWords = <String>[];
for (final subField in subFields) {
if (!itemJson.containsKey(subField)) continue;
final value = itemJson[subField];
if (value is List) {
for (final v in value) {
fieldWords.addAll(EnhancedSmartSearch.splitWords(v.toString()));
}
} else if (value != null) {
fieldWords.addAll(EnhancedSmartSearch.splitWords(value.toString()));
}
}
final fieldScore = EnhancedSmartSearch.itemScore(
fieldWords,
queryWordGroups,
useDamerauLevenshtein,
useNGram,
);
totalScore += fieldScore * weight;
totalWeight += weight;
});
final score = totalWeight > 0 ? totalScore / totalWeight : 0.0;
results.add(SmartSearchResult<T>(item, score));
}
// Sort by score descending
results.sort((a, b) => b.score.compareTo(a.score));
return results;
}