Skip to content
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

[Feature] Add pagination settings #264

Merged
merged 9 commits into from
Mar 20, 2023
9 changes: 9 additions & 0 deletions lib/src/index.dart
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,15 @@ abstract class MeiliSearchIndex {
/// Update typo tolerance settings of the index.
Future<Task> updateTypoTolerance(TypoTolerance typoTolerance);

/// Get pagination settings of the index.
Future<Pagination> getPagination();

/// Reset pagination settings of the index.
Future<Task> resetPagination();

/// Update pagination settings of the index.
Future<Task> updatePagination(Pagination pagination);

/// Reset the settings of the index.
/// All settings will be reset to their default value.
Future<Task> resetSettings();
Expand Down
26 changes: 26 additions & 0 deletions lib/src/index_impl.dart
Original file line number Diff line number Diff line change
Expand Up @@ -639,6 +639,32 @@ class MeiliSearchIndexImpl implements MeiliSearchIndex {
);
}

@override
Future<Pagination> getPagination() async {
final response = await http.getMethod<Map<String, Object?>>(
'/indexes/$uid/settings/pagination',
);

return Pagination.fromMap(response.data!);
}

@override
Future<Task> resetPagination() async {
return await _getTask(
http.deleteMethod('/indexes/$uid/settings/pagination'),
);
}

@override
Future<Task> updatePagination(Pagination pagination) async {
return await _getTask(
http.patchMethod(
'/indexes/$uid/settings/pagination',
data: pagination.toMap(),
),
);
}

///
/// Stats endponts
///
Expand Down
1 change: 1 addition & 0 deletions lib/src/settings/_exports.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@
export 'index_settings.dart';
export 'min_word_size_for_typos.dart';
export 'typo_tolerance.dart';
export 'pagination.dart';
12 changes: 11 additions & 1 deletion lib/src/settings/index_settings.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import 'pagination.dart';
import 'typo_tolerance.dart';

class IndexSettings {
Expand All @@ -11,6 +12,7 @@ class IndexSettings {
this.searchableAttributes = allAttributes,
this.displayedAttributes = allAttributes,
this.typoTolerance,
this.pagination,
});

static const allAttributes = <String>['*'];
Expand Down Expand Up @@ -42,6 +44,9 @@ class IndexSettings {
/// Customize typo tolerance feature.
TypoTolerance? typoTolerance;

///Customize pagination feature.
Pagination? pagination;

Map<String, Object?> toMap() => <String, Object?>{
'synonyms': synonyms,
'stopWords': stopWords,
Expand All @@ -51,11 +56,13 @@ class IndexSettings {
'searchableAttributes': searchableAttributes,
'displayedAttributes': displayedAttributes,
'sortableAttributes': sortableAttributes,
'typoTolerance': typoTolerance?.toMap()
'typoTolerance': typoTolerance?.toMap(),
'pagination': pagination?.toMap(),
};

factory IndexSettings.fromMap(Map<String, Object?> map) {
final typoTolerance = map['typoTolerance'];
final pagination = map['pagination'];
final synonyms = map['synonyms'];
final stopWords = map['stopWords'];
final rankingRules = map['rankingRules'];
Expand Down Expand Up @@ -90,6 +97,9 @@ class IndexSettings {
typoTolerance: typoTolerance is Map<String, Object?>
? TypoTolerance.fromMap(typoTolerance)
: null,
pagination: pagination is Map<String, Object?>
? Pagination.fromMap(pagination)
: null,
);
}
}
23 changes: 23 additions & 0 deletions lib/src/settings/pagination.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
const _defaultMaxTotalHits = 1000;

class Pagination {
///Define the maximum number of documents reachable for a search request.
///It means that with the default value of `1000`, it is not possible to see the `1001`st result for a **search query**.
int maxTotalHits;

Pagination({
this.maxTotalHits = _defaultMaxTotalHits,
});

Map<String, dynamic> toMap() {
return {
'maxTotalHits': maxTotalHits,
};
}

factory Pagination.fromMap(Map<String, dynamic> map) {
return Pagination(
maxTotalHits: map['maxTotalHits'] as int? ?? _defaultMaxTotalHits,
);
}
}
68 changes: 68 additions & 0 deletions test/settings_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,7 @@ void main() {
final initial = await index.getTypoTolerance();
final initialFromSettings =
await index.getSettings().then((value) => value.typoTolerance);

expect(
initial.toMap(),
equals(initialFromSettings?.toMap()),
Expand All @@ -275,6 +276,7 @@ void main() {
final afterUpdate = await index.getTypoTolerance();
final afterUpdateFromSettings =
await index.getSettings().then((value) => value.typoTolerance);

expect(
afterUpdateFromSettings?.toMap(),
equals(toUpdate.toMap()),
Expand Down Expand Up @@ -305,5 +307,71 @@ void main() {
);
});
});

group('Pagination', () {
late MeiliSearchIndex index;
setUp(() async {
final uid = randomUid();
await client.createIndex(uid).waitFor(client: client);
index = await client.getIndex(uid);
});

Future<Pagination> doUpdate() async {
final toUpdate = Pagination(
maxTotalHits: 2000,
);
var response =
await index.updatePagination(toUpdate).waitFor(client: client);

expect(response.status, "succeeded");
return toUpdate;
}

test("Get", () async {
final initial = await index.getPagination();
final initialFromSettings =
await index.getSettings().then((value) => value.pagination);

expect(
initial.toMap(),
equals(initialFromSettings?.toMap()),
);
});

test("Update", () async {
final toUpdate = await doUpdate();

final afterUpdate = await index.getPagination();
final afterUpdateFromSettings =
await index.getSettings().then((value) => value.pagination);
expect(
afterUpdateFromSettings?.toMap(),
equals(toUpdate.toMap()),
);
expect(
afterUpdate.toMap(),
equals(toUpdate.toMap()),
);
});

test("Reset", () async {
//first update, then reset
await doUpdate();
final response = await index.resetPagination().waitFor(client: client);

expect(response.status, 'succeeded');
final afterReset = await index.getPagination();
final afterResetFromSettings =
await index.getSettings().then((value) => value.pagination);
expect(
afterReset.toMap(),
equals(Pagination().toMap()),
);
expect(
afterResetFromSettings?.toMap(),
equals(Pagination().toMap()),
);
});
});
});
}