-
Notifications
You must be signed in to change notification settings - Fork 26
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add Result container #350
Add Result container #350
Changes from 11 commits
1dc8eb4
9e12faa
a9854d8
9e5e5ed
e683d69
3d04019
6f0fbd8
35ddb33
7c86107
affe32d
e7980d4
0c3f5ca
fab1ea4
6ebd988
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -125,6 +125,35 @@ | |
return Task.fromMap(response.data!); | ||
} | ||
|
||
/// Get the status of all experimental features that can be toggled at runtime | ||
@RequiredMeiliServerVersion('1.3.0') | ||
Future<ExperimentalFeatures> getExperimentalFeatures() async { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We did not provide these kinds of methods to the other SDKs. I understand they are very convenient during development but we believe they are not useful after that, since you only enable/disable once :) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I can mark them as internal as a warning to users to not use this There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think that's ok to keep, my concern is because it is more code to maintain and it will be present only in this SDK :) |
||
final response = await http.getMethod<Map<String, Object?>>( | ||
'/experimental-features', | ||
); | ||
return ExperimentalFeatures.fromJson(response.data!); | ||
} | ||
|
||
/// Set the status of experimental features that can be toggled at runtime | ||
@RequiredMeiliServerVersion('1.3.0') | ||
Future<ExperimentalFeatures> updateExperimentalFeatures( | ||
UpdateExperimentalFeatures input, | ||
) async { | ||
final inputJson = input.toJson(); | ||
if (inputJson.isEmpty) { | ||
throw ArgumentError.value( | ||
input, | ||
'input', | ||
'input must contain at least one entry', | ||
); | ||
} | ||
final response = await http.patchMethod<Map<String, Object?>>( | ||
'/experimental-features', | ||
data: input.toJson(), | ||
); | ||
return ExperimentalFeatures.fromJson(response.data!); | ||
} | ||
|
||
/// Return health of the Meilisearch server. | ||
/// Throws an error if containing details if Meilisearch can't process your request. | ||
Future<Map<String, dynamic>> health() async { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -29,6 +29,9 @@ | |
super.highlightPostTag, | ||
super.matchingStrategy, | ||
super.attributesToSearchOn, | ||
super.showRankingScore, | ||
super.vector, | ||
super.showRankingScoreDetails, | ||
}); | ||
|
||
@override | ||
|
@@ -62,6 +65,9 @@ | |
String? highlightPostTag, | ||
MatchingStrategy? matchingStrategy, | ||
List<String>? attributesToSearchOn, | ||
bool? showRankingScore, | ||
List<dynamic /* double | List<double> */ >? vector, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. wish dart had type unions 😢 |
||
bool? showRankingScoreDetails, | ||
}) => | ||
IndexSearchQuery( | ||
query: query ?? this.query, | ||
|
@@ -85,5 +91,9 @@ | |
highlightPostTag: highlightPostTag ?? this.highlightPostTag, | ||
matchingStrategy: matchingStrategy ?? this.matchingStrategy, | ||
attributesToSearchOn: attributesToSearchOn ?? this.attributesToSearchOn, | ||
showRankingScore: showRankingScore ?? this.showRankingScore, | ||
vector: vector ?? this.vector, | ||
showRankingScoreDetails: | ||
showRankingScoreDetails ?? this.showRankingScoreDetails, | ||
); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,163 @@ | ||
import 'package:meilisearch/src/annotations.dart'; | ||
|
||
import 'match_position.dart'; | ||
import 'ranking_rules/base.dart'; | ||
import 'searchable.dart'; | ||
|
||
/// A class that wraps around documents returned from meilisearch to provide useful information. | ||
final class MeiliDocumentContainer<T extends Object> { | ||
const MeiliDocumentContainer._({ | ||
required this.rankingScoreDetails, | ||
required this.src, | ||
required this.parsed, | ||
required this.formatted, | ||
required this.vectors, | ||
required this.semanticScore, | ||
required this.rankingScore, | ||
required this.matchesPosition, | ||
}); | ||
|
||
final Map<String, dynamic> src; | ||
final T parsed; | ||
final Map<String, dynamic>? formatted; | ||
@RequiredMeiliServerVersion('1.3.0') | ||
final List<dynamic /* double | List<double> */ >? vectors; | ||
@RequiredMeiliServerVersion('1.3.0') | ||
final double? semanticScore; | ||
@RequiredMeiliServerVersion('1.3.0') | ||
final double? rankingScore; | ||
@RequiredMeiliServerVersion('1.3.0') | ||
final MeiliRankingScoreDetails? rankingScoreDetails; | ||
|
||
/// Contains the location of each occurrence of queried terms across all fields | ||
final Map<String, List<MatchPosition>>? matchesPosition; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this was incorrectly placed in |
||
|
||
dynamic operator [](String key) => src[key]; | ||
dynamic getFormatted(String key) => formatted?[key]; | ||
|
||
dynamic getFormattedOrSrc(String key) => getFormatted(key) ?? this[key]; | ||
Comment on lines
+35
to
+38
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. convenience methods |
||
|
||
static MeiliDocumentContainer<Map<String, dynamic>> fromJson( | ||
Map<String, dynamic> src, | ||
) { | ||
final rankingScoreDetails = | ||
src['_rankingScoreDetails'] as Map<String, dynamic>?; | ||
return MeiliDocumentContainer<Map<String, dynamic>>._( | ||
src: src, | ||
parsed: src, | ||
formatted: src['_formatted'] as Map<String, dynamic>?, | ||
vectors: src['_vectors'] as List?, | ||
semanticScore: src['_semanticScore'] as double?, | ||
rankingScore: src['_rankingScore'] as double?, | ||
matchesPosition: _readMatchesPosition(src), | ||
rankingScoreDetails: rankingScoreDetails == null | ||
? null | ||
: MeiliRankingScoreDetails.fromJson(rankingScoreDetails), | ||
); | ||
} | ||
|
||
MeiliDocumentContainer<TOther> map<TOther extends Object>( | ||
MeilisearchDocumentMapper<T, TOther> mapper, | ||
) { | ||
return MeiliDocumentContainer._( | ||
src: src, | ||
parsed: mapper(parsed), | ||
formatted: formatted, | ||
vectors: vectors, | ||
semanticScore: semanticScore, | ||
rankingScore: rankingScore, | ||
rankingScoreDetails: rankingScoreDetails, | ||
matchesPosition: matchesPosition); | ||
} | ||
|
||
@override | ||
String toString() => src.toString(); | ||
} | ||
|
||
class MeiliRankingScoreDetails { | ||
const MeiliRankingScoreDetails._({ | ||
required this.src, | ||
required this.words, | ||
required this.typo, | ||
required this.proximity, | ||
required this.attribute, | ||
required this.exactness, | ||
required this.customRules, | ||
}); | ||
final Map<String, dynamic> src; | ||
final MeiliRankingScoreDetailsWordsRule? words; | ||
final MeiliRankingScoreDetailsTypoRule? typo; | ||
final MeiliRankingScoreDetailsProximityRule? proximity; | ||
final MeiliRankingScoreDetailsAttributeRule? attribute; | ||
final MeiliRankingScoreDetailsExactnessRule? exactness; | ||
final Map<String, MeiliRankingScoreDetailsCustomRule> customRules; | ||
|
||
factory MeiliRankingScoreDetails.fromJson(Map<String, dynamic> src) { | ||
final reservedKeys = { | ||
'attribute', | ||
'words', | ||
'exactness', | ||
'proximity', | ||
'typo', | ||
}; | ||
|
||
T? ruleGuarded<T>( | ||
String key, | ||
T Function(Map<String, dynamic> src) mapper, | ||
) { | ||
final v = src[key]; | ||
if (v == null) { | ||
return null; | ||
} | ||
return mapper(v as Map<String, dynamic>); | ||
} | ||
|
||
return MeiliRankingScoreDetails._( | ||
src: src, | ||
attribute: ruleGuarded( | ||
'attribute', | ||
MeiliRankingScoreDetailsAttributeRule.fromJson, | ||
), | ||
words: ruleGuarded( | ||
'words', | ||
MeiliRankingScoreDetailsWordsRule.fromJson, | ||
), | ||
exactness: ruleGuarded( | ||
'exactness', | ||
MeiliRankingScoreDetailsExactnessRule.fromJson, | ||
), | ||
proximity: ruleGuarded( | ||
'proximity', | ||
MeiliRankingScoreDetailsProximityRule.fromJson, | ||
), | ||
typo: ruleGuarded( | ||
'typo', | ||
MeiliRankingScoreDetailsTypoRule.fromJson, | ||
), | ||
customRules: { | ||
for (var custom in src.entries | ||
.where((element) => !reservedKeys.contains(element.key))) | ||
custom.key: MeiliRankingScoreDetailsCustomRule.fromJson( | ||
custom.value as Map<String, dynamic>, | ||
) | ||
Comment on lines
+138
to
+142
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I haven't had a chance to test this, since I have no idea when a custom rule is returned |
||
}, | ||
); | ||
} | ||
} | ||
|
||
Map<String, List<MatchPosition>>? _readMatchesPosition( | ||
Map<String, Object?> map, | ||
) { | ||
final src = map['_matchesPosition']; | ||
|
||
if (src == null) return null; | ||
|
||
return (src as Map<String, Object?>).map( | ||
(key, value) => MapEntry( | ||
key, | ||
(value as List<Object?>) | ||
.map((e) => MatchPosition.fromMap(e as Map<String, Object?>)) | ||
.toList(), | ||
), | ||
); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
import 'package:json_annotation/json_annotation.dart'; | ||
|
||
part 'experimental_features.g.dart'; | ||
|
||
@JsonSerializable( | ||
createFactory: true, | ||
createToJson: false, | ||
) | ||
class ExperimentalFeatures { | ||
@JsonKey(name: 'vectorStore') | ||
final bool vectorStore; | ||
@JsonKey(name: 'scoreDetails') | ||
final bool scoreDetails; | ||
|
||
const ExperimentalFeatures({ | ||
required this.vectorStore, | ||
required this.scoreDetails, | ||
}); | ||
|
||
factory ExperimentalFeatures.fromJson(Map<String, dynamic> src) { | ||
return _$ExperimentalFeaturesFromJson(src); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this method is generated using |
||
} | ||
} | ||
|
||
@JsonSerializable( | ||
includeIfNull: false, | ||
createToJson: true, | ||
createFactory: false, | ||
) | ||
class UpdateExperimentalFeatures { | ||
@JsonKey(name: 'vectorStore') | ||
final bool? vectorStore; | ||
@JsonKey(name: 'scoreDetails') | ||
final bool? scoreDetails; | ||
|
||
const UpdateExperimentalFeatures({ | ||
this.vectorStore, | ||
this.scoreDetails, | ||
}); | ||
|
||
Map<String, dynamic> toJson() => _$UpdateExperimentalFeaturesToJson(this); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this method is generated using |
||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
dart test
by default uses concurrency