NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
pub.dev · #5151 most downloaded on pub.dev
Meilisearch Dart is the Meilisearch API client for Dart and Flutter developers.
Last release 6 months ago
01 Apr 2026
Release timing varies
gaps range from 8 days to 1.1 years
Nearly every release is documented
notes for 35 of 36 stable releases
Nothing withdrawn
no release was ever pulled
6 years old
39 releases · first in 2020
One column per quarter.
Add replication and sharding support via network API ( #480 ) @Strift
Add ID as a parameter for GetDocuments ( #461 ) @M4dhav
bors.toml configuration file (#455)Thanks again to @M4dhav, @Strift, @ahmednfwela, @brunoocasali, @curquiza, @dependabot[bot], @meili-bors[bot], and dependabot[bot]! 🎉
No breaking change but addition of new features
Implement rankingScoreThreshold as search query parameter ( #436 ) @memishood
rankingScoreThreshold as search query parameter (#436) @memishoodThanks again to @Strift, @ahmednfwela, @curquiza, @dependabot[bot], @meili-bors[bot], @memishood and dependabot[bot]! 🎉
implement experimental ai-powered search ( #398 ) @memishood
Thanks again to @Strift, @ahmednfwela, @curquiza, @guimachiavelli, @meili-bors[bot], and @memishood! 🎉
This version introduces features released on Meilisearch v1.7.0 🎉 Check out the changelog of Meilisearch v1.7.0 for more information on the changes.
This version introduces features released on Meilisearch v1.7.0 🎉
Check out the changelog of Meilisearch v1.7.0 for more information on the changes.
scoreDetails feature is not experimental anymore. You can directly use showRankingScoreDetails during a search without activating the experimental feature 🎉Checkout the full CHANGELOG here: https://github.com/meilisearch/meilisearch-dart/blob/main/CHANGELOG.md
Checkout the full CHANGELOG here: https://github.com/meilisearch/meilisearch-dart/blob/main/CHANGELOG.md
Thanks again to @ahmednfwela, @brunoocasali, @curquiza, @justkahdri, @meili-bors[bot] ! 🎉
Faceting to be final, and remove the default valuesSearcheable<T> fields in the constructor as requiredSearcheable<T> had a wrong matchesPosition property, which was moved into MeiliDocumentContainer<T>int? total to TasksResultsattributesToSearchOn to SearchQuery and IndexSearchQueryFuture<FacetSearchResult> facetSearch(FacetSearchQuery query) to MeiliSearchIndexenum FacetingSortTypesMap<String, FacetingSortTypes>? sortFacetValuesBy to FacetingList? vector to SearchQuery and IndexSearchQuerybool? showRankingScoreDetails to SearchQuery and IndexSearchQuerybool? showRankingScore to SearchQuery and IndexSearchQueryMeiliDocumentContainer<T>Map<String, dynamic> src to Searchable which exposes the raw json object returned from the server.
Just in case we don't keep up with new meilisearch releases, the user has a way to access new features.[experimental]* To adopt a experimental change you must opt-in manually
Still, even being supported, the ability to receive only a list of ids is deprecated , and it will be removed soon.
This version introduces features released on Meilisearch v1.2.0 🎉
Check out the changelog of Meilisearch v1.2.0 for more information on the changes.
⚠️ If you want to adopt new features of this release, update the Meilisearch server to the according version.
Check the complete CHANGELOG here: https://github.com/meilisearch/meilisearch-dart/blob/main/CHANGELOG.md
The method deleteDocuments() now supports a different behavior. This method now takes a DeleteDocumentsQuery, which could contain the filter or the ids (aka old behavior). #318 @ahmednfwela
⚠️ You must configure the attributes you want to filter using the MeiliSearchIndex.filterableAttributes().
⚠️ Remember to update your Meilisearch server to v1.2.0 or newer before adopting it.
Still, even being supported, the ability to receive only a list of ids is deprecated, and it will be removed soon.
// from:
- Future<Task> deleteDocuments(List<Object> ids)
+ Future<Task> deleteDocuments(DeleteDocumentsQuery query)
// to:
- index.deleteDocuments([456, 4])
+ index.deleteDocuments(DeleteDocumentsQuery(ids: [456, 4]))Add the ability to set filter in the DocumentsQuery. When a query with a filter is sent to getDocuments(params: DocumentsQuery) it will filter the documents like the search method. See the docs on how to use filters. #318 @ahmednfwela
⚠️ You must configure the attributes you want to filter using the MeiliSearchIndex.filterableAttributes().
⚠️ Remember to update your Meilisearch server to v1.2.0 or newer before adopting it.
MeiliSearchIndex.search now takes a String query and a SearchQuery object as the only inputs. #310 @ahmednfwela
index.search('xyz', ....) with index.search('xyz', SearchQuery(....))- await client.index('books').search('query', sort: [], filter: ...);
+ await client.index('books').search('query', SearchQuery(sort: [], filter: ...));Meili.geoBoundingBox and Meili.geoRadius now take record values to represent the lat/lng points: #310 @ahmednfwela
// Confusing, unclear
- Meili.geoBoundingBox(3,5.3,10,20)
// Not Confusing :)
+ Meili.geoBoundingBox((lat: 3, lng: 5.3), (lat: 10, lng: 20))// Confusing, unclear
- Meili.geoRadius(3, 5.3, 100)
// Not Confusing :)
+ Meili.geoRadius((lat: 3, lng: 5.3), 100)Change MultiSearchQuery.queries to be a List<IndexSearchQuery> instead of a List<SearchQuery>: #310 @ahmednfwela
final result = await client.multiSearch(MultiSearchQuery(queries: [
- SearchQuery(
+ IndexSearchQuery(
query: "",
indexUid: index1.uid,
),
- SearchQuery(
+ IndexSearchQuery(
query: "",
indexUid: index2.uid,
),
];RequiredMeiliServerVersion which documents the version these members were introduced. #310 @ahmednfwelaIS NULL, IS NOT NULL, IS EMPTY, IS NOT EMPTY. #310 @ahmednfwelafilter, filterExpression parameter to DocumentsQuery. #310 @ahmednfwelaQueryable refactoring to unify its behavior and avoid duplicating the code. #310 @ahmednfwelajsonEncoding attribute names when using filterExpressions #310 @ahmednfwelaIndexSearchQuery which extends SearchQuery. #310 @ahmednfwela
copyWith to SearchQuery and IndexSearchQuery #310 @ahmednfwelaThanks again to @brunoocasali, @ahmednfwela! 🎉
indexUid, query from SearchQuery to the new IndexSearchQuery.deleteDocuments signature:// from:
- Future<Task> deleteDocuments(List<Object> ids)
+ Future<Task> deleteDocuments(DeleteDocumentsQuery query)
// to:
- index.deleteDocuments([456, 4])
+ index.deleteDocuments(DeleteDocumentsQuery(ids: [456, 4]))
MeiliSearchIndex.search now takes a String query and a SearchQuery object as the only inputs.
index.search('xyz', ....) with index.search('xyz', SearchQuery(....))- await client.index('books').search('query', sort: [], filter: ...);
+ await client.index('books').search('query', SearchQuery(sort: [], filter: ...));
Meili.geoBoundingBox and Meili.geoRadius now take record values to represent the lat/lng points:// Confusing, unclear
- Meili.geoBoundingBox(3,5.3,10,20)
// Not Confusing :)
+ Meili.geoBoundingBox((lat: 3, lng: 5.3), (lat: 10, lng: 20))
// Confusing, unclear
- Meili.geoRadius(3, 5.3, 100)
// Not Confusing :)
+ Meili.geoRadius((lat: 3, lng: 5.3), 100)
MultiSearchQuery.queries to be a List<IndexSearchQuery> instead of a List<SearchQuery>:final result = await client.multiSearch(MultiSearchQuery(queries: [
- SearchQuery(
+ IndexSearchQuery(
query: "",
indexUid: index1.uid,
),
- SearchQuery(
+ IndexSearchQuery(
query: "",
indexUid: index2.uid,
),
];
RequiredMeiliServerVersion which documents the version this members were introduced.IS NULL, IS NOT NULL, IS EMPTY, IS NOT EMPTY.filter, filterExpression parameter to DocumentsQuery.Queryable refactoring to unify its behavior and avoid duplicating the code.jsonEncoding attribute names when using filterExpressionsIndexSearchQuery which extends SearchQuery.
copyWith to SearchQuery and IndexSearchQueryRaise minimum supported Dart runtime SDK to v3.0.0 ( #307 ) @ahmednfwela
Thanks again to @ahmednfwela and @brunoocasali! 🎉
This version introduces features released on Meilisearch v1.1.0 🎉 Check out the changelog of Meilisearch v1.1.0 for more information on the changes.
This version introduces features released on Meilisearch v1.1.0 🎉
Check out the changelog of Meilisearch v1.1.0 for more information on the changes.
facetStats, facetDistributions, and matchesPosition (#296) @ahmednfwela_geoBoundingBox in filterExpression parameter (#297) @ahmednfwelaThanks again to @ahmednfwela, @brunoocasali, @curquiza! 🎉
SwapIndex class has a new assert to require at least two items in the this.indexes attribute.FacetStat, MatchPosition.Searchable<T> to have proper types:- final Object? facetDistribution;
+ final Map<String, Map<String, int>>? facetDistribution;
- final Object? matchesPosition;
+ final Map<String, List<MatchPosition>>? matchesPosition;
+ final Map<String, FacetStat>? facetStats;
csvDelimiter parameter to addDocumentsCsv, addDocumentsCsvInBatches, updateDocumentsCsv, updateDocumentsCsvInBatches MeiliSearchIndex methods._geoBoundingBox in filterExpressionMake searchable.dart public available ( #290 , #289 ) @ahmednfwela
Thanks again to @ahmednfwela, @brunoocasali ! 🎉
Changes Searcheable, SearchResult, PaginatedSearchResult signatures to be generic Searcheable , SearchResult , PaginatedSearchResult
Searcheable, SearchResult, PaginatedSearchResult signatures to be generic Searcheable<T>, SearchResult<T>, PaginatedSearchResult<T>map<TOther> method to Searcheable<T> and its subclasses to map the search result to a different type.Searcheable<Map<String, dynamic>> by default, which can be mapped to other types using the map<TOther> method.Object? types that were changed from dynamic:
MeiliSearchClient class Future<Map<String, dynamic>> health();HttpRequest class Map<String, dynamic> headers();MeiliSearchIndex class Future<Searcheable<Map<String, dynamic>>> search(...);MeiliSearchIndex classFuture<Map<String, dynamic>?> getDocument(Object id, {List<String> fields});MeiliSearchIndex class Future<Result<Map<String, dynamic>>> getDocuments({DocumentsQuery? params});Searcheable<T>.hits is non-nullable now, and defaults to const []Future<Searchable<T>> to the corresponding type:final result = await index.search('').then((value) => (value as SearchResult<Map<String, dynamic>>).map(BookDto.fromMap));
final resultPaginated = await index.search('').then((value) => (value as PaginatedSearchResult<Map<String, dynamic>>).map(BookDto.fromMap));
to:
final result = await index.search('').asSearchResult().map(BookDto.fromMap);
final resultPaginated = await index.search('').asPaginatedResult().map(BookDto.fromMap);
Introduce MultiSearchQuery class to handle search requests.
MultiSearchQuery class to handle search requests.Future<MultiSearchResult> multiSearch(MultiSearchQuery requests); to MeiliSearchClient.Fix the behavior of client.index.getTasks() where the indexUid was not changing correctly after consecutive calls.
client.index.getTasks() where the indexUid was not changing correctly after consecutive calls.Add pagination settings methods Future getPagination(), Future resetPagination(), Future updatePagination(Pagination pagination) on Index instances.
Add pagination settings methods Future<Pagination> getPagination(), Future<Task> resetPagination(), Future<Task> updatePagination(Pagination pagination) on Index instances.
Add faceting settings methods Future<Faceting> getFaceting(), Future<Task> resetFaceting(), Future<Task> updateFaceting(Faceting faceting) on Index instances.
Add typo tolerance settings methods Future<TypoTolerance> getTypoTolerance(), Future<Task> resetTypoTolerance(), Future<Task> updateTypoTolerance(TypoTolerance typoTolerance) on Index instances.
Add filter-builder style:
Added filterExpression parameter to the search method, which takes a MeiliOperatorExpressionBase, you can only use the new parameter or the regular filter parameter, but not both. If both are provided, filter parameter will take priority.
Added new facade class Meili which contains static methods to help create filter expressions.
Added extension method toMeiliAttribute() to String, which is equivalent to Meili.attr.
Added extension method toMeiliValue() to String,num,DateTime,bool, which are equivalent to Meili.value.
example:
This query await index.search('prince', filterExpression: Meili.eq(Meili.attribute('tag'), Meili.value("Tale"))); is the same as await index.search('prince', filter: "tag = Tale").
Add Future<List<Task>> addDocumentsInBatches(List<Map<String, Object?>> documents, { int batchSize = 1000, String? primaryKey }) to Index instances.
Add Future<List<Task>> updateDocumentsInBatches(List<Map<String, Object?>> documents, { int batchSize = 1000, String? primaryKey }) to Index instances.
Add support to create documents from ndJson and CSV formats directly from Index with addDocumentsNdjson, addDocumentsCsv, updateDocumentsNdjson, and updateDocumentsCsv methods.
Add support for Dio adapter customization with MeiliSearchClient.withCustomDio(url, apiKey: "secret", interceptors: [interceptor]) (e.g: you can use this to inject custom code, support to HTTP/2 and more)
Special thanks to @ahmednfwela :tada:
[web] Fix a bug that affected the web platform regarding the override of User-Agent. Now the header used to send the client name information is the X-
User-Agent. Now the header used to send the client name information is the X-Meilisearch-Client one.The minimum supported Dart runtime is now 2.15.
The minimum supported Dart runtime is now 2.15.
Updated dio dependency from v4 to v5.
MeiliSearchClientImpl.connectTimeout, MeiliSearchClient.connectTimeout is now a Duration instead of int, and the default is Duration(seconds: 5).
From Future<Response<T>> getMethod<T>(String path, {Map<String, dynamic>? queryParameters,}); to Future<Response<T>> getMethod<T>(String path, { Object? data, Map<String, Object?>? queryParameters })
Reduce usage of dynamic keyword by replacing it with Object?.
Queryable.toQuery was promoted from Map<String, dynamic> to Map<String, Object> due to the use of removeEmptyOrNullsResult<T> had argument type T that was never used, so it was changed from List<dynamic> results; to List<T> results; and introduced a new helper function Result<TTarget> map<TTarget>(TTarget Function(T item) converter).getDocuments changed signature from Future<Result> getDocuments({DocumentsQuery? params}); to Future<Result<Map<String, Object?>>> getDocuments({DocumentsQuery? params});, and now end users can call .map on the result to use their own DTO classes (using fromJson for example).Future<Task> deleteDocuments(List<dynamic> ids); to Future<Task> deleteDocuments(List<Object> ids); since deleting a null id was an illegal operation.Future<Task> deleteDocument(dynamic id); to Future<Task> deleteDocument(Object id);Future<Task> updateDocuments(List<Map<String, dynamic>> documents, {String? primaryKey}); to Future<Task> updateDocuments(List<Map<String, Object?>> documents, {String? primaryKey});Future<Task> addDocuments(List<Map<String, dynamic>> documents, {String? primaryKey}); to Future<Task> addDocuments(List<Map<String, Object?>> documents, {String? primaryKey});Future<Task> deleteDocument(dynamic id); to Future<Task> deleteDocument(Object id);Future<Map<String, dynamic>?> getDocument(dynamic id, {List<String> fields}); to Future<Map<String, Object?>?> getDocument(Object id, {List<String> fields});Future<Searcheable> search(String? query, {...dynamic filter...}) is now a Object? filterFuture<Map<String, dynamic>> getRawIndex(String uid); to Future<Map<String, Object?>> getRawIndex(String uid);Future<Map<String, dynamic>> health(); to Future<Map<String, Object?>> health();String generateTenantToken(String uid, dynamic searchRules,... to String generateTenantToken(String uid, Object? searchRules,...class TasksResults<T> { ... } to class TasksResults { ... }uid.TasksQuery#canceledBy field is now a List and not an int? anymore.
TasksQuery#canceledBy field is now a List<int> and not an int? anymore.indexUid to TaskPaginatedSearchResultDocumentsQueryTasksQueryCancelTasksQueryDeleteTasksQueryKeysTasksQueryIndexesTasksQueryMatchingStrategy enumMeiliSearchApiException and CommunicationExceptionTask and TaskErrorSwapIndexRemove dart:mirrors dependency. Enable flutter and web platforms again.
dart:mirrors dependency. Enable flutter and web platforms again.⚠️ Don't use this version if you're using with Flutter or Web. It is not supported due to a mistake in the implementation of the Queryable class. Plea
⚠️ Don't use this version if you're using with Flutter or Web. It is not supported due to a mistake in the implementation of the Queryable class.
Please use the next available version.
SearchResult now is returned from search requests when is a non-exhaustive pagination request. A instance of PaginatedSearchResult is returned when the request was made with finite pagination.Future<Task> swapIndexes(List<SwapIndex> swaps) method to swap indexes.Future<Task> cancelTasks({CancelTasksQuery? params}) to cancel tasks based on the input query params.
CancelTasksQuery has these fields:
int? next;DateTime? beforeEnqueuedAt;DateTime? afterEnqueuedAt;DateTime? beforeStartedAt;DateTime? afterStartedAt;DateTime? beforeFinishedAt;DateTime? afterFinishedAt;List<int> uids;List<String> statuses;List<String> types;List<String> indexUids;Future<Task> deleteTasks({DeleteTasksQuery? params}) delete old processed tasks based on the input query params.
DeleteTasksQuery has these fields:
int? next;DateTime? beforeEnqueuedAt;DateTime? afterEnqueuedAt;DateTime? beforeStartedAt;DateTime? afterStartedAt;DateTime? beforeFinishedAt;DateTime? afterFinishedAt;List<int> canceledBy;List<int> uids;List<String> statuses;List<String> types;List<String> indexUids;TasksQuery has new fields, and some of them were renamed:
int? canceledBy;DateTime? beforeEnqueuedAt;DateTime? afterEnqueuedAt;DateTime? beforeStartedAt;DateTime? afterStartedAt;DateTime? beforeFinishedAt;DateTime? afterFinishedAt;List<int> uids;List<String> statuses; from List<String> status;List<String> types; from List<String> type;List<String> indexUids; from List<String> indexUid;Add support to matchingStrategy in the search MeiliSearchIndex#search.
matchingStrategy in the search MeiliSearchIndex#search.This version makes this package compatible with Meilisearch v0.28.0 and newer
This version makes this package compatible with Meilisearch v0.28.0 and newer
MeiliSearchClient#getDumpStatus method was removed.MeiliSearchClient#getIndexes method now return a object type Result<MeiliSearchIndex>.TaskInfo, TaskImpl, ClientTaskImpl are now just Task.
getStatus was removed in the new class.MeiliSearchClient#generateTenantToken now require a String uid which is the uid of the Key instance used to sign the token.MeiliSearchClient#createDump now responds with Task.MeiliSearchClient#getKeys method now return a object type Future<Result<Key>>.MeiliSearchClient#updateKey now can just update a description and/or name.MeiliSearchClient#getTasks method now return a object type Future<TasksResults>.MeiliSearchIndex#getTasks method now return a object type Future<TasksResults>.MeiliSearchIndex#search facetsDistribution is now facetsMeiliSearchIndex#search matches is now showMatchesPositionMeiliSearchIndex#getDocuments method now return a object type Future<Result>.MeiliSearchIndex#getDocuments method now accepts a object as a parameter and offset, limit, attributesToRetrieve were not longer accepted.nbHits, exhaustiveNbHits, facetsDistribution, exhaustiveFacetsCount were removed from SearchResult.T in MeiliSearchClient#search methodMeiliSearchClient#getIndexes accepts a object IndexesQuery to filter and paginate the results.MeiliSearchClient#getKeys accepts a object KeysQuery to filter and paginate the results.MeiliSearchClient#getKey accepts both a Key#uid or Key#key value.MeiliSearchClient#getTasks accepts a object TasksQuery to filter and paginate the results.MeiliSearchIndex#getTasks accepts a object TasksQuery to filter and paginate the results.MeiliSearchClient#createKey can specify a uid (optionally) to create a new Key.MeiliSearchIndex#getDocuments accepts a object DocumentsQuery to filter and paginate the results.Key has now a name and uid string fields.MeiliSearchIndex#getDocument accepts a list of fields to reduce the final payload.estimatedTotalHits, facetDistribution were added to SearchResultuid or apiKey will raise InvalidApiKeyException in the generateTenantToken.This version makes this package compatible with Meilisearch v0.27.0 and newer
This version makes this package compatible with Meilisearch v0.27.0 and newer
highlightPreTag, highlightPostTag, cropMarker, parameters in the search request (#156) @brunoocasali* Added new method generateTenantToken() as a result of the addition of the multi-tenant functionality. This method creates a JWT tenant token that wi
generateTenantToken() as a result of the addition of the multi-tenant functionality.
This method creates a JWT tenant token that will allow the user to have multi-tenant indexes and thus restrict access to documents based on the end-user making the search request. (#139) @brunoocasaliAdd User-Agent header to have analytics in every http request (#129) @brunoocasali
User-Agent header to have analytics in every http request (#129) @brunoocasaliThis version makes this package compatible with Meilisearch v0.25.0 and newer
This version makes this package compatible with Meilisearch v0.25.0 and newer
client.getRawIndex (#124) @brunoocasalipub upgrade in dependencies (#128) @brunoocasaliKey to represent keysclient.getKeysclient.getKeyclient.createKeyclient.updateKeyclient.deleteKeygetOrCreate from MeiliSearchClient (#119) @brunoocasaliPendingUpdate to TaskInfo (#123) @brunoocasaliAuthorization header instead of X-Meili-API-Key (#121) @brunoocasaliclient.getUpdateStatus to client.getTaskclient.getAllUpdateStatus to client.getTasksclient.getKeys responds with a Future<List<Key>> not Future<Map<String, String>>index.update, index.delete, client.createIndex, client.deleteIndex and client.updateIndex now responds with Future<TaskInfo>index.getAllUpdateStatus to index.getTasksindex.getUpdateStatus to index.getTaskRename errorCode, errorType and errorLink into code, type and link in the error handler (#110) @curquiza
errorCode, errorType and errorLink into code, type and link in the error handler (#110) @curquizaAdd json content type by default as header to make it compatible with Meilisearch v0.23.0 (#89) @curquiza
This version makes this package compatible with Meilisearch v0.21.0
This version makes this package compatible with Meilisearch v0.21.0
Changes due to the implicit index creation (#48) @alallema
Add health method (#38) @alallema
- Upgrade dependencies
Fix: Rename facetDistribution into facetsDistribution
Nothing published for this version
- Add example project
- Fix image in pub.dev listing
- Initial stable release - Write unit tests
- Implemented search endpoints - Implemented settings endpoints - Implemented document endpoints
Nothing published for this version
- Initial pre-release
Your coding agent can read these notes before it upgrades. Set up the MCP server →