diff --git a/.code-samples.meilisearch.yaml b/.code-samples.meilisearch.yaml
index 991d978a..db106fe8 100644
--- a/.code-samples.meilisearch.yaml
+++ b/.code-samples.meilisearch.yaml
@@ -1,133 +1,55 @@
-# This code-samples file is used by the Meilisearch documentation
+# This code-samples file is used by the Meilisearch documentation & landing page.
# Every example written here will be automatically fetched by
-# the documentation on build
-# You can read more on https://github.com/meilisearch/documentation/tree/master/.vuepress/code-samples
+# the documentation and the landing page on build
---
-search_parameter_guide_show_ranking_score_1: |-
- await client.index('movies').search('dragon', SearchQuery(showRankingScore: true));
-facet_search_2: |-
- await client.index('books').updateFaceting(Faceting(sortFacetValuesBy: {'genres': 'count'}));
-search_parameter_guide_attributes_to_search_on_1: |-
- await client.index('movies').search('adventure', SearchQuery(attributesToSearchOn: ['overview']));
-get_documents_post_1: |-
- await client.index('movies').getDocuments(
- params: DocumentsQuery(
- filter: '(rating > 3 AND (genres = Adventure OR genres = Fiction)) AND language = English',
- fields: ['title', 'genres', 'rating', 'language'],
- limit: 3
- )
- );
-delete_documents_by_filter_1: |-
- await client.index('movies')
- .deleteDocuments(DeleteDocumentsQuery(filter: 'genres = action OR genres = adventure'));
-get_documents_1: |-
- await client.index('movies')
- .getDocuments(params: DocumentsQuery(limit: 2, filter: 'genres = action'));
-multi_search_1: |-
- await client.multiSearch(MultiSearchQuery(queries: [
- IndexSearchQuery(
- query: "pooh",
- indexUid: "movies",
- limit: 5
- ),
- IndexSearchQuery(
- query: "nemo",
- indexUid: "movies",
- limit: 5
- ),
- IndexSearchQuery(
- query: "us",
- indexUid: "movies_ratings"
- ),
- ]));
-faceted_search_2: |-
- await client.multiSearch(MultiSearchQuery(queries: [
- IndexSearchQuery(
- indexUid: 'books',
- facets: ['language', 'genres', 'author', 'format'],
- filter: '(language = English AND language = French) OR genres = Fiction'
- ),
- IndexSearchQuery(
- indexUid: 'books',
- facets: ['language'],
- filter: 'genres = Fiction'
- ),
- IndexSearchQuery(
- indexUid: "books",
- facets: ['genres'],
- filter: 'language = English OR language = French'
- ),
- ]));
-faceted_search_update_settings_1: |-
- await client.index('movie_ratings').updateFilterableAttributes(['genres', 'rating', 'language']);
-search_parameter_guide_facet_stats_1: |-
- await client.index('movie_ratings').search('Batman', SearchQuery(facets: ['genres', 'rating']));
-faceted_search_1: |-
- await client.index('books').search('', SearchQuery(facets: ['genres', 'rating', 'language']));
-filtering_guide_nested_1: |-
- await client.index('movie_ratings').search('thriller', SearchQuery(filter: 'rating.users >= 90'));
-sorting_guide_sort_nested_1: |-
- await client.index('movie_ratings').search('thriller', SearchQuery(sort: ["rating.users:asc"]));
-async_guide_filter_by_date_1: |-
- await client.getTasks(params: TasksQuery(afterEnqueuedAt: DateTime(2020, 10, 11, 11, 49, 53)));
-async_guide_multiple_filters_1: |-
- await client.getTasks(params: TasksQuery(indexUids: ['movies'], types: ['documentAdditionOrUpdate','documentDeletion'], statuses: ['processing']));
-async_guide_filter_by_ids_1: |-
- await client.getTasks(params: TasksQuery(uids: [5, 10, 13]));
-async_guide_filter_by_statuses_1: |-
- await client.getTasks(params: TasksQuery(statuses: ['failed', 'canceled']));
-async_guide_filter_by_types_1: |-
- await client.getTasks(params: TasksQuery(types: ['dumpCreation', 'indexSwap']));
+search_parameter_guide_show_ranking_score_1: "await client\n .index('movies')\n .search('dragon', SearchQuery(showRankingScore: true));"
+facet_search_1: "await client.index('books').facetSearch(\n FacetSearchQuery(\n facetQuery: 'fiction',\n facetName: 'genres',\n filter: 'rating > 3',\n ),\n );"
+facet_search_2: "await client.index('books').updateFaceting(\n Faceting(\n sortFacetValuesBy: {\n 'genres': FacetingSortTypes.count,\n },\n ),\n );"
+facet_search_3: "await client.index('books').facetSearch(\n FacetSearchQuery(\n facetQuery: 'c',\n facetName: 'genres',\n ),\n );"
+search_parameter_guide_attributes_to_search_on_1: "await client.index('books').facetSearch(\n FacetSearchQuery(\n facetQuery: 'c',\n facetName: 'genres',\n ),\n );"
+get_documents_post_1: "await client.index('movies').getDocuments(\n params: DocumentsQuery(\n filterExpression: Meili.and([\n 'language'.toMeiliAttribute().eq('English'.toMeiliValue()),\n Meili.and([\n 'rating'.toMeiliAttribute().gt(3.toMeiliValue()),\n Meili.or([\n 'genres'.toMeiliAttribute().eq('Adventure'.toMeiliValue()),\n 'genres'.toMeiliAttribute().eq('Fiction'.toMeiliValue()),\n ]),\n ]),\n ]),\n fields: ['title', 'genres', 'rating', 'language'],\n limit: 3,\n ),\n );"
+delete_documents_by_filter_1: "await client.index('movies').deleteDocuments(\n DeleteDocumentsQuery(\n filterExpression: Meili.or([\n Meili.attr('genres').eq(Meili.value('action')),\n Meili.attr('genres').eq(Meili.value('adventure')),\n ]),\n ),\n );"
+get_documents_1: "await client.index('movies').getDocuments(\n params: DocumentsQuery(\n limit: 2,\n filter: Meili.attr('genres').eq('action'.toMeiliValue()),\n ),\n );"
+multi_search_1: "await client.multiSearch(MultiSearchQuery(queries: [\n IndexSearchQuery(query: 'pooh', indexUid: 'movies', limit: 5),\n IndexSearchQuery(query: 'nemo', indexUid: 'movies', limit: 5),\n IndexSearchQuery(query: 'us', indexUid: 'movies_ratings'),\n]));"
+faceted_search_update_settings_1: "await client\n .index('movie_ratings')\n .updateFilterableAttributes(['genres', 'rating', 'language']);"
+search_parameter_guide_facet_stats_1: "await client\n .index('movie_ratings')\n .search('Batman', SearchQuery(facets: ['genres', 'rating']));"
+faceted_search_1: "await client\n .index('books')\n .search('', SearchQuery(facets: ['genres', 'rating', 'language']));"
+filtering_guide_nested_1: "await client.index('movie_ratings').search(\n 'thriller',\n SearchQuery(\n filterExpression: Meili.gte(\n \/\/or Meili.attr('rating.users')\n \/\/or 'rating.users'.toMeiliAttribute()\n Meili.attrFromParts(['rating', 'users']),\n Meili.value(90),\n ),\n ),\n );"
+sorting_guide_sort_nested_1: "await client\n .index('movie_ratings')\n .search('thriller', SearchQuery(sort: ['rating.users:asc']));"
+async_guide_filter_by_date_1: "await client.getTasks(\n params: TasksQuery(\n afterEnqueuedAt: DateTime(2020, 10, 11, 11, 49, 53),\n ),\n);"
+async_guide_multiple_filters_1: "await client.getTasks(\n params: TasksQuery(\n indexUids: ['movies'],\n types: ['documentAdditionOrUpdate', 'documentDeletion'],\n statuses: ['processing'],\n ),\n);"
+async_guide_filter_by_ids_1: "await client.getTasks(\n params: TasksQuery(\n uids: [5, 10, 13],\n ),\n);"
+async_guide_filter_by_statuses_1: "await client.getTasks(\n params: TasksQuery(\n statuses: ['failed', 'canceled'],\n ),\n);"
+async_guide_filter_by_types_1: "await client.getTasks(\n params: TasksQuery(\n types: ['dumpCreation', 'indexSwap'],\n ),\n);"
async_guide_filter_by_index_uids_1: |-
await client.getTasks(params: TasksQuery(indexUids: ['movies']));
delete_tasks_1: |-
await client.deleteTasks(params: DeleteTasksQuery(uids: [1, 2]));
cancel_tasks_1: |-
await client.cancelTasks(params: CancelTasksQuery(uids: [1, 2]));
-async_guide_canceled_by: |-
- await client.getTasks(params: TasksQuery(canceledBy: [9]));
-swap_indexes_1: |-
- await client.swapIndexes([SwapIndex(['indexA', 'indexB']), SwapIndex(['indexX', 'indexY'])]);
-search_parameter_guide_hitsperpage_1: |-
- await client.index('movies').search('', SearchQuery(hitsPerPage: 15)) as PaginatedSearchResult;
-search_parameter_guide_page_1: |-
- await client.index('movies').search('', SearchQuery(page: 2)) as PaginatedSearchResult;
-synonyms_guide_1: |-
- await client.index('movies').updateSynonyms({
- 'great': ['fantastic'],
- 'fantastic': ['great']
- });
-date_guide_index_1: |-
- import 'dart:io';
- import 'dart:convert';
-
- final json = await File('games.json').readAsString();
-
- await client.index('games').addDocumentsJson(json);
-date_guide_filterable_attributes_1: |-
- await client.index('games').updateFilterableAttributes(['release_timestamp']);
-date_guide_filter_1: |-
- await client.index('games').search('',
- SearchQuery(filter:
- 'release_timestamp >= 1514761200 AND release_timestamp < 1672527600'));
-date_guide_sortable_attributes_1: |-
- await client.index('games').updateSortableAttributes(['release_timestamp']);
-date_guide_sort_1: |-
- await client.index('games').search('', SearchQuery(sort: ['release_timestamp:desc']));
+async_guide_canceled_by_1: |-
+ await client.getTasks(params: TasksQuery(canceledBy: [9, 15]));
+swap_indexes_1: "await client.swapIndexes([\n SwapIndex(['indexA', 'indexB']),\n SwapIndex(['indexX', 'indexY']),\n]);"
+search_parameter_guide_hitsperpage_1: "await client\n .index('movies')\n .search('', SearchQuery(hitsPerPage: 15))\n .asPaginatedResult();"
+search_parameter_guide_page_1: "await client\n .index('movies')\n .search('', SearchQuery(page: 2))\n .asPaginatedResult();"
+synonyms_guide_1: "await client.index('movies').updateSynonyms({\n 'great': ['fantastic'],\n 'fantastic': ['great'],\n});"
+date_guide_index_1: "\/\/import 'dart:io';\n\/\/import 'dart:convert';\nfinal json = await File('games.json').readAsString();\nawait client.index('games').addDocumentsJson(json);"
+date_guide_filterable_attributes_1: "await client\n .index('games')\n .updateFilterableAttributes(['release_timestamp']);"
+date_guide_filter_1: "await client.index('games').search(\n '',\n SearchQuery(\n filterExpression: Meili.and([\n Meili.gte(\n 'release_timestamp'.toMeiliAttribute(),\n Meili.value(DateTime(2017, 12, 31, 23, 0)),\n ),\n Meili.lt(\n 'release_timestamp'.toMeiliAttribute(),\n Meili.value(DateTime(2022, 12, 31, 23, 0)),\n ),\n ]),\n ),\n );"
+date_guide_sortable_attributes_1: "await client\n .index('games')\n .updateSortableAttributes(['release_timestamp']);"
+date_guide_sort_1: "await client\n .index('games')\n .search('', SearchQuery(sort: ['release_timestamp:desc']));"
get_all_tasks_paginating_1: |-
await client.getTasks(params: TasksQuery(limit: 2, from: 10));
get_all_tasks_paginating_2: |-
await client.getTasks(params: TasksQuery(limit: 2, from: 8));
get_pagination_settings_1: |-
await client.index('movies').getPagination();
-update_pagination_settings_1: |-
- await client.index('books').updatePagination(Pagination(maxTotalHits: 100));
+update_pagination_settings_1: "await client\n .index('books')\n .updatePagination(Pagination(maxTotalHits: 100));"
reset_pagination_settings_1: |-
await client.index('movies').resetPagination();
get_faceting_settings_1: |-
await client.index('movies').getFaceting();
-update_faceting_settings_1: |-
- await client.index('books').updateFaceting(Faceting(maxValuesPerFacet: 2, sortFacetValuesBy: {'*': 'alpha', 'genres': 'count'}));
+update_faceting_settings_1: "await client.index('books').updateFaceting(Faceting(\n maxValuesPerFacet: 2,\n sortFacetValuesBy: {\n '*': FacetingSortTypes.alpha,\n 'genres': FacetingSortTypes.count\n }));"
reset_faceting_settings_1: |-
await client.index('movies').resetFaceting();
get_one_index_1: |-
@@ -140,8 +62,7 @@ update_an_index_1: |-
await client.index('movies').update(primaryKey: 'id');
delete_an_index_1: |-
await client.index('movies').delete();
-get_one_document_1: |-
- await client.index('movies').getDocument(25684, fields: ['id', 'title', 'poster', 'release_date']);
+get_one_document_1: "await client.index('movies').getDocument(25684,\n fields: ['id', 'title', 'poster', 'release_date']);"
add_or_replace_documents_1: |-
await client.index('movies').addDocuments([
{
@@ -154,65 +75,26 @@ add_or_replace_documents_1: |-
'release_date': '2019-03-23'
}
]);
-add_or_update_documents_1: |-
- await client.index('movies').updateDocuments([
- {
- 'id': 287947,
- 'title': 'Shazam ⚡️',
- 'genres': 'comedy'
- }
- ]);
+add_or_update_documents_1: "await client.index('movies').updateDocuments([\n {\n 'id': 287947,\n 'title': 'Shazam ⚡️',\n 'genres': 'comedy',\n }\n]);"
delete_all_documents_1: |-
await client.index('movies').deleteAllDocuments();
delete_one_document_1: |-
await client.index('movies').deleteDocument(25684);
-delete_documents_by_batch_1: |-
- await client.index('movies')
- .deleteDocuments(DeleteDocumentsQuery(ids: [23488, 153738, 437035, 363869]));
+delete_documents_by_batch_1: "await client.index('movies').deleteDocuments(\n DeleteDocumentsQuery(\n ids: [23488, 153738, 437035, 363869],\n ),\n );"
search_post_1: |-
await client.index('movies').search('American ninja');
get_task_1: |-
await client.getTask(1);
get_all_tasks_1: |-
await client.getTasks();
-get_keys_1: |-
- await client.getKeys();
get_settings_1: |-
await client.index('movies').getSettings();
-update_settings_1: |-
- await client.index('movies').updateSettings(IndexSettings(
- rankingRules: [
- 'words',
- 'typo',
- 'proximity',
- 'attribute',
- 'sort',
- 'exactness',
- 'release_date:desc',
- 'rank:desc'
- ],
- distinctAttribute: 'movie_id',
- searchableAttributes: ['title', 'overview', 'genres'],
- displayedAttributes: ['title', 'overview', 'genres', 'release_date'],
- stopWords: ['the', 'a', 'an'],
- sortableAttributes: ['title', 'release_date'],
- synonyms: {
- 'wolverine': ['xmen', 'logan'],
- 'logan': ['wolverine'],
- },
- ));
+update_settings_1: "await client.index('movies').updateSettings(\n IndexSettings(\n rankingRules: [\n 'words',\n 'typo',\n 'proximity',\n 'attribute',\n 'sort',\n 'exactness',\n 'release_date:desc',\n 'rank:desc'\n ],\n distinctAttribute: 'movie_id',\n searchableAttributes: ['title', 'overview', 'genres'],\n displayedAttributes: [\n 'title',\n 'overview',\n 'genres',\n 'release_date'\n ],\n stopWords: ['the', 'a', 'an'],\n sortableAttributes: ['title', 'release_date'],\n synonyms: {\n 'wolverine': ['xmen', 'logan'],\n 'logan': ['wolverine'],\n },\n ),\n );"
reset_settings_1: |-
await client.index('movies').resetSettings();
get_synonyms_1: |-
await client.index('movies').getSynonyms();
-update_synonyms_1: |-
- await client.index('movies').updateSynonyms(
- {
- 'wolverine': ['xmen', 'logan'],
- 'logan': ['wolverine', 'xmen'],
- 'wow': ['world of warcraft']
- }
- );
+update_synonyms_1: "await client.index('movies').updateSynonyms({\n 'wolverine': ['xmen', 'logan'],\n 'logan': ['wolverine', 'xmen'],\n 'wow': ['world of warcraft'],\n});"
reset_synonyms_1: |-
await client.index('movies').resetSynonyms();
get_stop_words_1: |-
@@ -223,17 +105,7 @@ reset_stop_words_1: |-
await client.index('movies').resetStopWords();
get_ranking_rules_1: |-
await client.index('movies').getRankingRules();
-update_ranking_rules_1: |-
- await client.index('movies').updateRankingRules([
- 'words',
- 'typo',
- 'proximity',
- 'attribute',
- 'sort',
- 'exactness',
- 'release_date:asc',
- 'rank:desc'
- ]);
+update_ranking_rules_1: "await client.index('movies').updateRankingRules([\n 'words',\n 'typo',\n 'proximity',\n 'attribute',\n 'sort',\n 'exactness',\n 'release_date:asc',\n 'rank:desc',\n]);"
reset_ranking_rules_1: |-
await client.index('movies').resetRankingRules();
get_distinct_attribute_1: |-
@@ -244,34 +116,32 @@ reset_distinct_attribute_1: |-
await client.index('shoes').resetDistinctAttribute();
get_filterable_attributes_1: |-
await client.index('movies').getFilterableAttributes();
-update_filterable_attributes_1: |-
- await client.index('movies').updateFilterableAttributes([
- 'genres',
- 'director'
- ]);
+update_filterable_attributes_1: "await client\n .index('movies')\n .updateFilterableAttributes(['genres', 'director']);"
reset_filterable_attributes_1: |-
await client.index('movies').resetFilterableAttributes();
get_searchable_attributes_1: |-
await client.index('movies').getSearchableAttributes();
-update_searchable_attributes_1: |-
- await client.index('movies').updateSearchableAttributes([
- 'title',
- 'overview',
- 'genres'
- ]);
+update_searchable_attributes_1: "await client\n .index('movies')\n .updateSearchableAttributes(['title', 'overview', 'genres']);"
reset_searchable_attributes_1: |-
await client.index('movies').resetSearchableAttributes();
get_displayed_attributes_1: |-
await client.index('movies').getDisplayedAttributes();
-update_displayed_attributes_1: |-
- await client.index('movies').updateDisplayedAttributes([
- 'title',
- 'overview',
- 'genres',
- 'release_date'
- ]);
+update_displayed_attributes_1: "await client.index('movies').updateDisplayedAttributes([\n 'title',\n 'overview',\n 'genres',\n 'release_date',\n]);"
reset_displayed_attributes_1: |-
await client.index('movies').resetDisplayedAttributes();
+get_typo_tolerance_1: |-
+ await client.index('books').getTypoTolerance();
+update_typo_tolerance_1: |-
+ final toUpdate = TypoTolerance(
+ minWordSizeForTypos: MinWordSizeForTypos(
+ oneTypo: 4,
+ twoTypos: 10,
+ ),
+ disableOnAttributes: ['title'],
+ );
+ await client.index('books').updateTypoTolerance(toUpdate);
+reset_typo_tolerance_1: |-
+ await client.index('books').resetTypoTolerance();
get_index_stats_1: |-
await client.index('movies').getStats();
get_indexes_stats_1: |-
@@ -282,58 +152,24 @@ get_version_1: |-
await client.getVersion();
distinct_attribute_guide_1: |-
await client.index('jackets').updateDistinctAttribute('product_id');
-field_properties_guide_searchable_1: |-
- await client.index('movies').updateSearchableAttributes(['title', 'overview', 'genres']);
-field_properties_guide_displayed_1: |-
- await client.index('movies').updateDisplayedAttributes(['title', 'overview', 'genres', 'release_date']);
-filtering_guide_1: |-
- await client
- .index('movie_ratings')
- .search('Avengers', SearchQuery(filter: 'release_date > 795484800'));
-filtering_guide_2: |-
- await client.index('movie_ratings')
- .search('Batman',
- SearchQuery(filter: 'release_date > 795484800 AND (director = "Tim Burton" OR director = "Christopher Nolan")'
- )
- );
-filtering_guide_3: |-
- await client.index('movie_ratings').search('Planet of the Apes',
- SearchQuery(filter: 'release_date > 1577884550 AND (NOT director = "Tim Burton")'));
+field_properties_guide_searchable_1: "await client\n .index('movies')\n .updateSearchableAttributes(['title', 'overview', 'genres']);"
+field_properties_guide_displayed_1: "await client.index('movies').updateDisplayedAttributes([\n 'title',\n 'overview',\n 'genres',\n 'release_date',\n]);"
+filtering_guide_1: "await client.index('movie_ratings').search(\n 'Avengers',\n SearchQuery(\n filterExpression: Meili.gt(\n Meili.attr('release_date'),\n DateTime.utc(1995, 3, 18).toMeiliValue(),\n ),\n ),\n );"
+filtering_guide_2: "await client.index('movie_ratings').search(\n 'Batman',\n SearchQuery(\n filterExpression: Meili.and([\n Meili.attr('release_date')\n .gt(DateTime.utc(1995, 3, 18).toMeiliValue()),\n Meili.or([\n 'director'.toMeiliAttribute().eq('Tim Burton'.toMeiliValue()),\n 'director'\n .toMeiliAttribute()\n .eq('Christopher Nolan'.toMeiliValue()),\n ]),\n ]),\n ),\n );"
+filtering_guide_3: "await client.index('movie_ratings').search(\n 'Planet of the Apes',\n SearchQuery(\n filterExpression: Meili.and([\n Meili.attr('release_date')\n .gt(DateTime.utc(2020, 1, 1, 13, 15, 50).toMeiliValue()),\n Meili.not(\n Meili.attr('director').eq(\"Tim Burton\".toMeiliValue()),\n ),\n ]),\n ),\n );"
search_parameter_guide_query_1: |-
await client.index('movies').search('shifu');
search_parameter_guide_offset_1: |-
await client.index('movies').search('shifu', SearchQuery(offset: 1));
search_parameter_guide_limit_1: |-
await client.index('movies').search('shifu', SearchQuery(limit: 2));
-search_parameter_guide_matching_strategy_1: |-
- await client.index('movies').search('big fat liar', SearchQuery(matchingStrategy: MatchingStrategy.last));
-search_parameter_guide_matching_strategy_2: |-
- await client.index('movies').search('big fat liar', SearchQuery(matchingStrategy: MatchingStrategy.all));
-search_parameter_guide_retrieve_1: |-
- await client
- .index('movies')
- .search('shifu', SearchQuery(attributesToRetrieve: ['overview', 'title']));
-search_parameter_guide_crop_1: |-
- await client
- .index('movies')
- .search('shifu', SearchQuery(attributesToCrop: ['overview'], cropLength: 5));
-search_parameter_guide_highlight_1: |-
- await client
- .index('movies')
- .search('winter feast', SearchQuery(attributesToHighlight: ['overview']));
-search_parameter_guide_show_matches_position_1: |-
- await client.index('movies').search('winter feast', SearchQuery(showMatchesPosition: true));
-add_movies_json_1: |-
- import 'dart:io';
- import 'dart:convert';
-
- final json = await File('movies.json').readAsString();
-
- await client.index('movies').addDocumentsJson(json);
-documents_guide_add_movie_1: |-
- await client.index('movies').addDocuments([
- { 'movie_id': '123sq178', 'title': 'Amélie Poulain' }
- ]);
+search_parameter_guide_matching_strategy_1: "await client.index('movies').search(\n 'big fat liar', SearchQuery(matchingStrategy: MatchingStrategy.last));"
+search_parameter_guide_matching_strategy_2: "await client.index('movies').search(\n 'big fat liar', SearchQuery(matchingStrategy: MatchingStrategy.all));"
+search_parameter_guide_retrieve_1: "await client.index('movies').search(\n 'shifu', SearchQuery(attributesToRetrieve: ['overview', 'title']));"
+search_parameter_guide_crop_1: "await client.index('movies').search(\n 'shifu', SearchQuery(attributesToCrop: ['overview'], cropLength: 5));"
+search_parameter_guide_highlight_1: "await client.index('movies').search(\n 'winter feast', SearchQuery(attributesToHighlight: ['overview']));"
+search_parameter_guide_show_matches_position_1: "await client\n .index('movies')\n .search('winter feast', SearchQuery(showMatchesPosition: true));"
+add_movies_json_1: "\/\/ import 'dart:io';\n\/\/ import 'dart:convert';\nfinal json = await File('movies.json').readAsString();\nawait client.index('movies').addDocumentsJson(json);"
primary_field_guide_create_index_primary_key: |-
await client.createIndex('books', primaryKey: 'reference_number');
primary_field_guide_update_document_primary_key: |-
@@ -348,147 +184,79 @@ primary_field_guide_add_document_primary_key: |-
'price': 5.00
}
], primaryKey: 'reference_number');
-getting_started_add_documents_md: |-
- ```bash
- dart pub add meilisearch
- ```
-
- ```dart
- import 'package:meilisearch/meilisearch.dart';
- import 'dart:io';
- import 'dart:convert';
-
- var client = MeiliSearchClient('http://localhost:7700', 'aSampleMasterKey');
-
- final json = await File('movies.json').readAsString();
-
- await client.index('movies').addDocumentsJson(json);
- ```
-
- [About this SDK](https://github.com/meilisearch/meilisearch-dart/)
-getting_started_search_md: |-
- ```dart
- await client.index('movies').search('botman');
- ```
-
- [About this SDK](https://github.com/meilisearch/meilisearch-dart/)
-getting_started_update_ranking_rules: |-
- await client.index('movies').updateRankingRules([
- 'exactness',
- 'words',
- 'typo',
- 'proximity',
- 'attribute',
- 'sort',
- 'release_date:asc',
- 'rank:desc'
- ]);
-getting_started_update_searchable_attributes: |-
- await client.index('movies').updateSearchableAttributes([
- 'title'
- ]);
+typo_tolerance_guide_1: |-
+ final toUpdate = TypoTolerance(enabled: false);
+ await client.index('movies').updateTypoTolerance(toUpdate);
+typo_tolerance_guide_2: |-
+ final toUpdate = TypoTolerance(
+ disableOnAttributes: ['title'],
+ );
+ await client.index('movies').updateTypoTolerance(toUpdate);
+typo_tolerance_guide_3: |-
+ final toUpdate = TypoTolerance(
+ disableOnWords: ['shrek'],
+ );
+ await client.index('movies').updateTypoTolerance(toUpdate);
+typo_tolerance_guide_4: |-
+ final toUpdate = TypoTolerance(
+ minWordSizeForTypos: MinWordSizeForTypos(
+ oneTypo: 4,
+ twoTypos: 10,
+ ),
+ );
+ await client.index('movies').updateTypoTolerance(toUpdate);
+getting_started_add_documents_md: "```bash\ndart pub add meilisearch\n```\n```dart\nimport 'package:meilisearch\/meilisearch.dart';\nimport 'dart:io';\nimport 'dart:convert';\nvar client = MeiliSearchClient('http:\/\/localhost:7700', 'aSampleMasterKey');\nfinal json = await File('movies.json').readAsString();\nawait client.index('movies').addDocumentsJson(json);\n```\n[About this SDK](https:\/\/github.com\/meilisearch\/meilisearch-dart\/)"
+getting_started_search_md: "```dart\nawait client.index('movies').search('botman');\n```\n[About this SDK](https:\/\/github.com\/meilisearch\/meilisearch-dart\/)"
+getting_started_update_ranking_rules: "await client.index('movies').updateRankingRules([\n 'exactness',\n 'words',\n 'typo',\n 'proximity',\n 'attribute',\n 'sort',\n 'release_date:asc',\n 'rank:desc',\n]);"
+getting_started_update_searchable_attributes: "await client.index('movies').updateSearchableAttributes(['title']);"
getting_started_update_stop_words: |-
await client.index('movies').updateStopWords(['the']);
getting_started_check_task_status: |-
await client.getTask(0);
-getting_started_synonyms: |-
- await client.index('movies').updateSynonyms({
- 'winnie': ['piglet'],
- 'piglet': ['winnie']
- });
-getting_started_update_displayed_attributes: |-
- await client.index('movies').updateDisplayedAttributes([
- 'title',
- 'overview',
- 'poster'
- ]);
-getting_started_communicating_with_a_protected_instance: |-
- var client = MeiliSearchClient('http://localhost:7700', 'apiKey');
- await client.index('movies').search('');
-getting_started_add_meteorites: |-
- final json = await File('meteorites.json').readAsString();
-
- await client.index('meteorites').addDocumentsJson(json);
-getting_started_configure_settings: |-
- await client.index('meteorites').updateSettings(IndexSettings(
- filterableAttributes: ['mass', '_geo'],
- sortableAttributes: ['mass', '_geo']
- ));
-getting_started_geo_radius: |-
- await client.index('meteorites').search('', SearchQuery(filter: '_geoRadius(46.9480, 7.4474, 210000)'));
-getting_started_geo_point: |-
- await client.index('meteorites').search('', SearchQuery(sort: ['_geoPoint(48.8583701, 2.2922926):asc']));
-getting_started_sorting: |-
- await client.index('meteorites').search('', SearchQuery(sort: ['mass:asc'], filter: 'mass < 200'));
-getting_started_filtering: |-
- await client.index('meteorites').search('', SearchQuery(filter: 'mass < 200'));
-getting_started_faceting: |-
- await client.index('books').updateFaceting(Faceting(maxValuesPerFacet: 2, sortFacetValuesBy: {'*': 'count'}));
+getting_started_synonyms: "await client.index('movies').updateSynonyms({\n 'winnie': ['piglet'],\n 'piglet': ['winnie'],\n});"
+getting_started_update_displayed_attributes: "await client\n .index('movies')\n .updateDisplayedAttributes(['title', 'overview', 'poster']);"
+getting_started_add_meteorites: "final json = await File('meteorites.json').readAsString();\nawait client.index('meteorites').addDocumentsJson(json);"
+getting_started_configure_settings: "await client.index('meteorites').updateSettings(IndexSettings(\n filterableAttributes: ['mass', '_geo'],\n sortableAttributes: ['mass', '_geo']));"
+getting_started_geo_radius: "await client.index('meteorites').search(\n '',\n SearchQuery(\n filterExpression: Meili.geoRadius(\n (lat: 46.9480, lng: 7.4474),\n 210000,\n ),\n ),\n );"
+getting_started_geo_point: "await client.index('meteorites').search(\n '', SearchQuery(sort: ['_geoPoint(48.8583701, 2.2922926):asc']));"
+getting_started_sorting: "await client.index('meteorites').search(\n '',\n SearchQuery(\n sort: ['mass:asc'],\n filterExpression: Meili.attr('mass').lt(200.toMeiliValue()),\n ),\n );"
+getting_started_filtering: "await client\n .index('meteorites')\n .search('', SearchQuery(filter: 'mass < 200'));"
+getting_started_faceting: "await client.index('books').updateFaceting(Faceting(\n maxValuesPerFacet: 2,\n sortFacetValuesBy: {'*': FacetingSortTypes.count}));"
getting_started_typo_tolerance: |-
final toUpdate = TypoTolerance(
minWordSizeForTypos: MinWordSizeForTypos(oneTypo: 4),
);
await client.index('movies').updateTypoTolerance(toUpdate);
-getting_started_pagination: |-
- await client.index('books').updatePagination(Pagination(maxTotalHits: 500));
+getting_started_pagination: "await client\n .index('books')\n .updatePagination(Pagination(maxTotalHits: 500));"
filtering_update_settings_1: |-
await client.index('movies').updateFilterableAttributes([
'director',
'genres',
]);
-faceted_search_facets_1: |-
- await client.index('movies').search('Batman', SearchQuery(facets: ['genres']));
-faceted_search_walkthrough_filter_1: |-
- await client.index('movies').search('thriller', SearchQuery(filter: [
- ['genres = Horror', 'genres = Mystery'],
- 'director = "Jordan Peele"'
- ]));
+faceted_search_walkthrough_filter_1: "await client.index('movies').search(\n 'thriller',\n SearchQuery(filter: [\n ['genres = Horror', 'genres = Mystery'],\n 'director = \"Jordan Peele\"'\n ]));"
post_dump_1: |-
await client.createDump();
phrase_search_1: |-
await client.index('movies').search('"african american" horror');
sorting_guide_update_sortable_attributes_1: |-
await client.index('books').updateSortableAttributes(['author', 'price']);
-sorting_guide_update_ranking_rules_1: |-
- await client.index('books').updateRankingRules([
- 'words',
- 'sort',
- 'typo',
- 'proximity',
- 'attribute',
- 'exactness'
- ]);
-sorting_guide_sort_parameter_1: |-
- await client.index('books').search('science fiction', SearchQuery(sort: ['price:asc']));
-sorting_guide_sort_parameter_2: |-
- await client.index('books').search('butler', SearchQuery(sort: ['author:desc']));
+sorting_guide_update_ranking_rules_1: "await client.index('books').updateRankingRules(\n ['words', 'sort', 'typo', 'proximity', 'attribute', 'exactness']);"
+sorting_guide_sort_parameter_1: "await client\n .index('books')\n .search('science fiction', SearchQuery(sort: ['price:asc']));"
+sorting_guide_sort_parameter_2: "await client\n .index('books')\n .search('butler', SearchQuery(sort: ['author:desc']));"
get_sortable_attributes_1: |-
await client.index('books').getSortableAttributes();
-update_sortable_attributes_1: |-
- await client.index('books').updateSortableAttributes([
- 'price',
- 'author'
- ]);
+update_sortable_attributes_1: "await client.index('books').updateSortableAttributes(['price', 'author']);"
reset_sortable_attributes_1: |-
await client.index('books').resetSortableAttributes();
-search_parameter_guide_sort_1: |-
- await client.index('books').search('science fiction', SearchQuery(sort: ['price:asc']));
+search_parameter_guide_sort_1: "await client\n .index('books')\n .search('science fiction', SearchQuery(sort: ['price:asc']));"
geosearch_guide_filter_settings_1: |-
await client.index('restaurants').updateFilterableAttributes(['_geo']);
-geosearch_guide_filter_usage_1: |-
- await await client
- .index('restaurants')
- .search('', SearchQuery(filter: '_geoRadius(45.472735, 9.184019, 2000)'));
-geosearch_guide_filter_usage_2: |-
- await await client
- .index('restaurants')
- .search('', SearchQuery(filter: '_geoRadius(45.472735, 9.184019, 2000) AND type = pizza'));
+geosearch_guide_filter_usage_1: "await client.index('restaurants').search(\n '',\n SearchQuery(\n filterExpression: Meili.geoRadius(\n (lat: 45.472735, lng: 9.184019),\n 2000,\n ),\n ),\n );"
+geosearch_guide_filter_usage_2: "await client.index('restaurants').search(\n '',\n SearchQuery(\n filterExpression: Meili.and([\n Meili.geoRadius(\n (lat: 45.472735, lng: 9.184019),\n 2000,\n ),\n Meili.attr('type').eq('pizza'.toMeiliValue())\n ]),\n ),\n );"
geosearch_guide_sort_settings_1: |-
await client.index('restaurants').updateSortableAttributes(['_geo']);
-geosearch_guide_sort_usage_1: |-
- await client.index('restaurants').search('', SearchQuery(sort: ['_geoPoint(48.8561446, 2.2978204):asc']));
-geosearch_guide_sort_usage_2: |-
- await client.index('restaurants').search('', SearchQuery(sort: ['_geoPoint(48.8561446, 2.2978204):asc', 'rating:desc']));
+geosearch_guide_sort_usage_1: "await client.index('restaurants').search(\n '', SearchQuery(sort: ['_geoPoint(48.8561446, 2.2978204):asc']));"
+geosearch_guide_sort_usage_2: "await client.index('restaurants').search(\n '',\n SearchQuery(\n sort: ['_geoPoint(48.8561446, 2.2978204):asc', 'rating:desc']));"
authorization_header_1: |-
var client = MeiliSearchClient('http://localhost:7700', 'masterKey');
await client.getKeys();
@@ -496,27 +264,14 @@ get_one_key_1: |-
await client.getKey('6062abda-a5aa-4414-ac91-ecd7944c0f8d');
get_all_keys_1: |-
await client.getKeys(params: KeysQuery(limit: 3));
-create_a_key_1: |-
- await client.createKey(
- description: 'Add documents: Products API key',
- actions: ['documents.add'],
- indexes: ['products'],
- expiresAt: DateTime(2042, 04, 02)
- );
-update_a_key_1: |-
- await client.updateKey(
- '6062abda-a5aa-4414-ac91-ecd7944c0f8d',
- description: 'Manage documents: Products/Reviews API key',
- name: 'Products/Reviews API key'
- );
+create_a_key_1: "await client.createKey(\n description: 'Add documents: Products API key',\n actions: ['documents.add'],\n indexes: ['products'],\n expiresAt: DateTime(2042, 04, 02));"
+update_a_key_1: "await client.updateKey(\n '6062abda-a5aa-4414-ac91-ecd7944c0f8d',\n description: 'Manage documents: Products\/Reviews API key',\n name: 'Products\/Reviews API key',\n);"
delete_a_key_1: |-
await client.deleteKey('6062abda-a5aa-4414-ac91-ecd7944c0f8d');
security_guide_search_key_1: |-
var client = MeiliSearchClient('http://localhost:7700', 'apiKey');
await client.index('patient_medical_records').search('');
-security_guide_update_key_1: |-
- var client = MeiliSearchClient('http://localhost:7700', 'masterKey');
- await client.updateKey('74c9c733-3368-4738-bbe5-1d18a5fecb37', description: 'Default Search API Key');
+security_guide_update_key_1: "var client = MeiliSearchClient('http:\/\/localhost:7700', 'masterKey');\nawait client.updateKey(\n '74c9c733-3368-4738-bbe5-1d18a5fecb37',\n description: 'Default Search API Key',\n);"
security_guide_create_key_1: |-
var client = MeiliSearchClient('http://localhost:7700', 'masterKey');
await client.createKey(
@@ -531,48 +286,7 @@ security_guide_list_keys_1: |-
security_guide_delete_key_1: |-
var client = MeiliSearchClient('http://localhost:7700', 'masterKey');
await client.deleteKey('ac5cd97d-5a4b-4226-a868-2d0eb6d197ab');
-tenant_token_guide_generate_sdk_1: |-
- final uid = '85c3c2f9-bdd6-41f1-abd8-11fcf80e0f76';
- final apiKey = 'B5KdX2MY2jV6EXfUs6scSfmC...';
- final expiresAt = DateTime.utc(2025, 12, 20);
- final searchRules = {
- 'patient_medical_records': {
- 'filter': 'user_id = 1'
- }
- };
-
- final token = client.generateTenantToken(
- uid,
- searchRules,
- apiKey: apiKey, // optional
- expiresAt: expiresAt // optional
- );
-tenant_token_guide_search_sdk_1: |-
- final frontEndClient = MeiliSearchClient('http://localhost:7700', token);
- await frontEndClient.index('patient_medical_records').search('blood test');
-landing_getting_started_1: |-
- var client = MeiliSearchClient('http://localhost:7700', 'masterKey');
-
- await client.index('movies').addDocuments([
- { 'id': 1, 'title': 'Carol' },
- { 'id': 2, 'title': 'Wonder Woman' },
- { 'id': 3, 'title': 'Life of Pi' },
- { 'id': 4, 'title': 'Mad Max: Fury Road' },
- { 'id': 5, 'title': 'Moana' },
- { 'id': 6, 'title': 'Philadelphia'}
- ]);
-search_parameter_guide_crop_marker_1: |-
- await client
- .index('movies')
- .search('shifu', SearchQuery(attributesToCrop: ['overview'], cropMarker: "[…]"));
-search_parameter_guide_highlight_tag_1: |-
- await client.index('movies').search(
- 'winter feast',
- SearchQuery(
- attributesToHighlight: ['overview'],
- highlightPreTag: '',
- highlightPostTag: ''));
-geosearch_guide_filter_usage_3: |-
- await client.index('restaurants')
- .search('', SearchQuery(filter: '_geoBoundingBox([45.494181, 9.214024], [45.449484, 9.179175])')),
- })
+search_parameter_guide_crop_marker_1: "await client.index('movies').search(\n 'shifu',\n SearchQuery(\n attributesToCrop: ['overview'],\n cropMarker: '[…]',\n ),\n );"
+search_parameter_guide_highlight_tag_1: "await client.index('movies').search(\n 'winter feast',\n SearchQuery(\n attributesToHighlight: ['overview'],\n highlightPreTag: '',\n highlightPostTag: '<\/span>',\n ),\n );"
+geosearch_guide_filter_usage_3: "await client.index('restaurants').search(\n '',\n SearchQuery(\n filter:\n '_geoBoundingBox([45.494181, 9.214024], [45.449484, 9.179175])'));\n});"
+search_get_1: await client.index('movies').search('American ninja');
diff --git a/.github/release-draft-template.yml b/.github/release-draft-template.yml
index e8adefa2..c1c4ac77 100644
--- a/.github/release-draft-template.yml
+++ b/.github/release-draft-template.yml
@@ -16,6 +16,10 @@ categories:
label: 'bug'
- title: '🔒 Security'
label: 'security'
+ - title: '⚙️ Maintenance/misc'
+ label:
+ - 'maintenance'
+ - 'documentation'
template: |
$CHANGES
diff --git a/.github/workflows/pre-release-tests.yml b/.github/workflows/pre-release-tests.yml
index a498df8c..5d7e43ec 100644
--- a/.github/workflows/pre-release-tests.yml
+++ b/.github/workflows/pre-release-tests.yml
@@ -21,10 +21,10 @@ jobs:
name: integration-tests-against-rc (dart ${{ matrix.version }})
steps:
- name: Checkout
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
- name: Get the latest Meilisearch RC
run: echo "MEILISEARCH_VERSION=$(curl https://raw.githubusercontent.com/meilisearch/integration-guides/main/scripts/get-latest-meilisearch-rc.sh | bash)" >> $GITHUB_ENV
- name: Meilisearch (${{ env.MEILISEARCH_VERSION }}) setup with Docker
run: docker run -d -p 7700:7700 getmeili/meilisearch:${{ env.MEILISEARCH_VERSION }} meilisearch --master-key=masterKey --no-analytics
- name: Run integration tests
- run: docker run --net="host" -v $PWD:/package -w /package dart:${{ matrix.version }} /bin/sh -c 'dart pub get && dart run test'
+ run: docker run --net="host" -v $PWD:/package -w /package dart:${{ matrix.version }} /bin/sh -c 'dart pub get && dart pub get -C tool && dart run test'
diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml
index b2ed242c..aed70f61 100644
--- a/.github/workflows/publish.yml
+++ b/.github/workflows/publish.yml
@@ -10,7 +10,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
- name: Check release validity
run: sh .github/scripts/check-release.sh
- name: Publish
diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
index 8f39a1fc..2bf37595 100644
--- a/.github/workflows/tests.yml
+++ b/.github/workflows/tests.yml
@@ -18,12 +18,11 @@ jobs:
# Will still run for each push to bump-meilisearch-v*
if: github.event_name != 'pull_request' || !startsWith(github.base_ref, 'bump-meilisearch-v')
timeout-minutes: 10
- runs-on: ${{ matrix.os }}
+ runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
- os: [ ubuntu-latest, macos-latest, windows-latest ]
- version: ['3.0.0']
+ version: ['latest']
name: integration-tests (dart ${{ matrix.version }})
services:
meilisearch:
@@ -35,23 +34,25 @@ jobs:
- 7700:7700
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- uses: dart-lang/setup-dart@v1
with:
sdk: ${{ matrix.version }}
- name: Install dependencies
run: |
dart pub get
+ dart pub get -C tool
dart pub global activate coverage
- name: Run integration tests
run: dart test --concurrency=4 --reporter=github --coverage=./coverage/reports
- name: Generate coverage reports
run: dart pub global run coverage:format_coverage --report-on=./lib --lcov --in=./coverage/reports --out=coverage/lcov.info
- name: Report to Codecov
- uses: codecov/codecov-action@v3
+ uses: codecov/codecov-action@v4
with:
file: coverage/lcov.info
- fail_ci_if_error: true
+ fail_ci_if_error: false
+
linter:
name: linter-check
@@ -59,12 +60,14 @@ jobs:
container:
image: dart:latest
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- uses: dart-lang/setup-dart@v1
with:
sdk: '3.0.0'
- name: Install dependencies
- run: dart pub get
+ run: |
+ dart pub get
+ dart pub get -C tool
- name: Run linter
run: dart analyze --fatal-infos && dart format . --set-exit-if-changed
@@ -72,19 +75,32 @@ jobs:
name: Yaml linting check
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- name: Yaml lint check
uses: ibiqlik/action-yamllint@v3
with:
config_file: .yamllint.yml
+ check-code-samples:
+ name: check .code-samples.meilisearch.yaml
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ - uses: dart-lang/setup-dart@v1
+ with:
+ sdk: 'latest'
+ - name: check if samples changed
+ run: |
+ dart pub get
+ dart pub get -C tool
+ dart run ./tool/bin/meili.dart update-samples --fail-on-change
pana:
runs-on: ubuntu-latest
timeout-minutes: 10
container:
image: dart:latest
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- uses: dart-lang/setup-dart@v1
with:
sdk: '3.0.0'
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 52a52aaa..2971b016 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,28 @@
[comment]: <> (All notable changes to this project will be documented in this file.)
+# 0.15.0
+### Breaking Changes:
+
+- Change members of `Faceting` to be `final`, and remove the default values
+- Mark all `Searcheable` fields in the constructor as `required`
+- Bug Fix `Searcheable` had a wrong `matchesPosition` property, which was moved into `MeiliDocumentContainer`
+
+### Changes:
+
+- Add `int? total` to `TasksResults`
+- Add `attributesToSearchOn` to `SearchQuery` and `IndexSearchQuery`
+- Add `Future facetSearch(FacetSearchQuery query)` to `MeiliSearchIndex`
+- Add `enum FacetingSortTypes`
+- Add `Map? sortFacetValuesBy` to `Faceting`
+- [experimental]* Add `List? vector` to `SearchQuery` and `IndexSearchQuery`
+- [experimental]* Add `bool? showRankingScoreDetails` to `SearchQuery` and `IndexSearchQuery`
+- Add `bool? showRankingScore` to `SearchQuery` and `IndexSearchQuery`
+- Add `MeiliDocumentContainer`
+- Add `Map 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](https://www.meilisearch.com/docs/learn/experimental/overview#activating-experimental-features)
+
# 0.14.0
### Breaking Changes:
- Moved `indexUid`, `query` from `SearchQuery` to the new `IndexSearchQuery`.
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index c7903028..eecd17b4 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -9,6 +9,7 @@ First of all, thank you for contributing to Meilisearch! The goal of this docume
- [Requirements ](#requirements-)
- [Setup ](#setup-)
- [Tests and Linter ](#tests-and-linter-)
+ - [Updating code samples](#updating-code-samples)
- [Git Guidelines](#git-guidelines)
- [Git Branches ](#git-branches-)
- [Git Commits ](#git-commits-)
@@ -76,6 +77,31 @@ dart test
dart analyze
```
+### Updating code samples
+
+Some PRs require updating the code samples (found in `.code-samples.meilisearch.yaml`), this is done automatically using code excerpts, which are actual pieces of code subject to testing and linting.
+
+A lot of them are placed in `test/code_samples.dart`.
+
+Also most of the tests in that file are skipped, since they are mostly duplicated in other test files.
+
+The process to define a new code sample is as follows:
+1. Add the piece of code in `test/code_samples.dart`
+2. surround it with `#docregion key` and `#enddocregion`, e.g.
+ ```
+ // #docregion meilisearch_contributing_1
+ final client = MeilisearchClient();
+ anything();
+ // #enddocregion
+ ```
+3. run this command to update the code samples
+ ```bash
+ dart run ./tool/bin/meili.dart update-samples
+ ```
+4. to test if the code samples are updated correctly, run:
+ ```bash
+ dart run ./tool/bin/meili.dart update-samples --fail-on-change
+ ```
## Git Guidelines
### Git Branches
diff --git a/LICENSE b/LICENSE
index 18221f6a..1600b0ab 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
MIT License
-Copyright (c) 2020-2022 Meili SAS
+Copyright (c) 2020-2024 Meili SAS
Copyright (c) 2020 Misir Jafarov
Permission is hereby granted, free of charge, to any person obtaining a copy
diff --git a/README.md b/README.md
index 0a912988..d3858d34 100644
--- a/README.md
+++ b/README.md
@@ -28,7 +28,7 @@
**Meilisearch** is an open-source search engine. [Learn more about Meilisearch.](https://github.com/meilisearch/meilisearch)
-## Table of Contents
+## Table of Contents
- [📖 Documentation](#-documentation)
- [⚡ Supercharge your Meilisearch experience](#-supercharge-your-meilisearch-experience)
@@ -55,7 +55,7 @@ You can install the **meilisearch** package by adding a few lines into `pubspec.
```yaml
dependencies:
- meilisearch: ^0.14.0
+ meilisearch: ^0.15.0
```
Then open your terminal and update dart packages.
@@ -202,6 +202,8 @@ await index.search('wonder', filter: ['id > 1 AND genres = Action']);
This package guarantees compatibility with [version v1.x of Meilisearch](https://github.com/meilisearch/meilisearch/releases/tag/latest), but some features may not be present. Please check the [issues](https://github.com/meilisearch/meilisearch-dart/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22+label%3Aenhancement) for more info.
+⚠️ This package is not compatible with the [`vectoreStore` experimental feature](https://www.meilisearch.com/docs/learn/experimental/vector_search) of Meilisearch v1.6.0 and later. More information on this [issue](https://github.com/meilisearch/meilisearch-dart/issues/369).
+
## 💡 Learn more
The following sections in our main documentation website may interest you:
diff --git a/bors.toml b/bors.toml
index cc14a4c6..e714ecb3 100644
--- a/bors.toml
+++ b/bors.toml
@@ -1,7 +1,7 @@
status = [
- 'integration-tests (dart 3.0.0)',
- 'linter-check',
- 'pana'
+ 'integration-tests (dart latest)',
+ 'linter-check',
+ 'pana'
]
# 1 hour timeout
timeout-sec = 3600
diff --git a/lib/src/filter_builder/operators.dart b/lib/src/filter_builder/operators.dart
index 4a970f7a..33549dd3 100644
--- a/lib/src/filter_builder/operators.dart
+++ b/lib/src/filter_builder/operators.dart
@@ -1,325 +1,325 @@
-import 'package:collection/collection.dart';
-import 'package:meilisearch/meilisearch.dart';
-
-import '../annotations.dart';
-
-const _eqUnordered = DeepCollectionEquality.unordered();
-
-typedef MeiliPoint = ({num lat, num lng});
-
-/// Represents an empty filter
-///
-/// works as a starting point for filter builders
-class MeiliEmptyExpression extends MeiliOperatorExpressionBase {
- const MeiliEmptyExpression();
-
- @override
- String transform() => "";
-}
-
-class MeiliAndOperatorExpression extends MeiliOperatorExpressionBase {
- final List operands;
-
- MeiliAndOperatorExpression({
- required MeiliOperatorExpressionBase first,
- required MeiliOperatorExpressionBase second,
- }) : this.fromList([first, second]);
-
- const MeiliAndOperatorExpression.fromList(this.operands);
-
- @override
- String transform() {
- //space is mandatory
- final filteredOperands = operands
- .map((e) => e.transform())
- .where((element) => element.isNotEmpty);
- if (filteredOperands.isEmpty) {
- return '';
- } else if (filteredOperands.length == 1) {
- return filteredOperands.first;
- } else {
- return filteredOperands.map((e) => '($e)').join(" AND ");
- }
- }
-
- @override
- bool operator ==(Object other) {
- if (identical(this, other)) return true;
-
- return other is MeiliAndOperatorExpression &&
- _eqUnordered.equals(other.operands, operands);
- }
-
- @override
- int get hashCode => Object.hash("AND", _eqUnordered.hash(operands));
-}
-
-class MeiliOrOperatorExpression extends MeiliOperatorExpressionBase {
- final List operands;
-
- MeiliOrOperatorExpression({
- required MeiliOperatorExpressionBase first,
- required MeiliOperatorExpressionBase second,
- }) : this.fromList([first, second]);
-
- const MeiliOrOperatorExpression.fromList(this.operands);
-
- @override
- String transform() {
- final filteredOperands = operands
- .map((e) => e.transform())
- .where((element) => element.isNotEmpty);
- if (filteredOperands.isEmpty) {
- return '';
- } else if (filteredOperands.length == 1) {
- return filteredOperands.first;
- } else {
- return filteredOperands.map((e) => '($e)').join(" OR ");
- }
- }
-
- @override
- bool operator ==(Object other) {
- if (identical(this, other)) return true;
-
- return other is MeiliOrOperatorExpression &&
- _eqUnordered.equals(other.operands, operands);
- }
-
- @override
- int get hashCode => Object.hash("OR", _eqUnordered.hash(operands));
-}
-
-class MeiliToOperatorExpression extends MeiliOperatorExpressionBase {
- final MeiliAttributeExpression attribute;
- final MeiliValueExpressionBase min;
- final MeiliValueExpressionBase max;
-
- const MeiliToOperatorExpression({
- required this.min,
- required this.max,
- required this.attribute,
- });
-
- @override
- String transform() {
- final attributeTransformed = attribute.transform();
- return "$attributeTransformed ${min.transform()} TO $attributeTransformed ${max.transform()}";
- }
-}
-
-class MeiliGeoRadiusOperatorExpression extends MeiliOperatorExpressionBase {
- final MeiliPoint point;
- final double distanceInMeters;
-
- const MeiliGeoRadiusOperatorExpression(
- this.point,
- this.distanceInMeters,
- );
-
- @override
- String transform() {
- return '_geoRadius(${point.lat},${point.lng},$distanceInMeters)';
- }
-}
-
-@RequiredMeiliServerVersion('1.1.0')
-class MeiliGeoBoundingBoxOperatorExpression
- extends MeiliOperatorExpressionBase {
- final MeiliPoint point1;
- final MeiliPoint point2;
-
- const MeiliGeoBoundingBoxOperatorExpression(
- this.point1,
- this.point2,
- );
-
- @override
- String transform() {
- return '_geoBoundingBox([${point1.lat},${point1.lng}],[${point2.lat},${point2.lng}])';
- }
-}
-
-class MeiliExistsOperatorExpression extends MeiliOperatorExpressionBase {
- final MeiliAttributeExpression attribute;
-
- const MeiliExistsOperatorExpression(this.attribute);
-
- @override
- String transform() {
- return "${attribute.transform()} EXISTS";
- }
-}
-
-class MeiliNotExistsOperatorExpression extends MeiliOperatorExpressionBase {
- final MeiliAttributeExpression attribute;
-
- const MeiliNotExistsOperatorExpression(this.attribute);
-
- @override
- String transform() {
- return "${attribute.transform()} NOT EXISTS";
- }
-}
-
-@RequiredMeiliServerVersion('1.2.0')
-class MeiliIsNullOperatorExpression extends MeiliOperatorExpressionBase {
- final MeiliAttributeExpression attribute;
-
- const MeiliIsNullOperatorExpression(this.attribute);
-
- @override
- String transform() {
- return "${attribute.transform()} IS NULL";
- }
-}
-
-@RequiredMeiliServerVersion('1.2.0')
-class MeiliIsNotNullOperatorExpression extends MeiliOperatorExpressionBase {
- final MeiliAttributeExpression attribute;
-
- const MeiliIsNotNullOperatorExpression(this.attribute);
-
- @override
- String transform() {
- return "${attribute.transform()} IS NOT NULL";
- }
-}
-
-@RequiredMeiliServerVersion('1.2.0')
-class MeiliIsEmptyOperatorExpression extends MeiliOperatorExpressionBase {
- final MeiliAttributeExpression attribute;
-
- const MeiliIsEmptyOperatorExpression(this.attribute);
-
- @override
- String transform() {
- return "${attribute.transform()} IS EMPTY";
- }
-}
-
-@RequiredMeiliServerVersion('1.2.0')
-class MeiliIsNotEmptyOperatorExpression extends MeiliOperatorExpressionBase {
- final MeiliAttributeExpression attribute;
-
- const MeiliIsNotEmptyOperatorExpression(this.attribute);
-
- @override
- String transform() {
- return "${attribute.transform()} IS NOT EMPTY";
- }
-}
-
-class MeiliNotOperatorExpression extends MeiliOperatorExpressionBase {
- final MeiliOperatorExpressionBase operator;
-
- const MeiliNotOperatorExpression(this.operator)
- : assert(operator is! MeiliEmptyExpression,
- "Cannot negate (NOT) an empty operator");
-
- @override
- String transform() {
- return "NOT ${operator.transform()}";
- }
-}
-
-class MeiliInOperatorExpression extends MeiliOperatorExpressionBase {
- final MeiliAttributeExpression attribute;
- final List values;
-
- const MeiliInOperatorExpression({
- required this.attribute,
- required this.values,
- });
-
- @override
- String transform() {
- //TODO(ahmednfwela): escape commas in values ?
- return "${attribute.transform()} IN [${values.map((e) => e.transform()).join(',')}]";
- }
-}
-
-/// Represents an operator that has a value as an operand
-abstract class MeiliValueOperandOperatorExpressionBase
- extends MeiliOperatorExpressionBase {
- final MeiliAttributeExpression property;
- final MeiliValueExpressionBase value;
-
- const MeiliValueOperandOperatorExpressionBase({
- required this.property,
- required this.value,
- });
-
- String get operator;
-
- @override
- String transform() {
- return '${property.transform()} $operator ${value.transform()}';
- }
-}
-
-class MeiliEqualsOperatorExpression
- extends MeiliValueOperandOperatorExpressionBase {
- const MeiliEqualsOperatorExpression({
- required MeiliAttributeExpression property,
- required MeiliValueExpressionBase value,
- }) : super(property: property, value: value);
-
- @override
- final String operator = "=";
-}
-
-class MeiliNotEqualsOperatorExpression
- extends MeiliValueOperandOperatorExpressionBase {
- const MeiliNotEqualsOperatorExpression({
- required MeiliAttributeExpression property,
- required MeiliValueExpressionBase value,
- }) : super(property: property, value: value);
-
- @override
- final String operator = "!=";
-}
-
-class MeiliGreaterThanOperatorExpression
- extends MeiliValueOperandOperatorExpressionBase {
- const MeiliGreaterThanOperatorExpression({
- required MeiliAttributeExpression property,
- required MeiliValueExpressionBase value,
- }) : super(property: property, value: value);
-
- @override
- final String operator = ">";
-}
-
-class MeiliGreaterThanEqualsOperatorExpression
- extends MeiliValueOperandOperatorExpressionBase {
- const MeiliGreaterThanEqualsOperatorExpression({
- required MeiliAttributeExpression property,
- required MeiliValueExpressionBase value,
- }) : super(property: property, value: value);
-
- @override
- final String operator = ">=";
-}
-
-class MeiliLessThanOperatorExpression
- extends MeiliValueOperandOperatorExpressionBase {
- const MeiliLessThanOperatorExpression({
- required MeiliAttributeExpression property,
- required MeiliValueExpressionBase value,
- }) : super(property: property, value: value);
-
- @override
- final String operator = "<";
-}
-
-class MeiliLessThanEqualsOperatorExpression
- extends MeiliValueOperandOperatorExpressionBase {
- const MeiliLessThanEqualsOperatorExpression({
- required MeiliAttributeExpression property,
- required MeiliValueExpressionBase value,
- }) : super(property: property, value: value);
-
- @override
- final String operator = "<=";
-}
+import 'package:collection/collection.dart';
+import 'package:meilisearch/meilisearch.dart';
+
+import '../annotations.dart';
+
+const _eqUnordered = DeepCollectionEquality.unordered();
+
+typedef MeiliPoint = ({num lat, num lng});
+
+/// Represents an empty filter
+///
+/// works as a starting point for filter builders
+class MeiliEmptyExpression extends MeiliOperatorExpressionBase {
+ const MeiliEmptyExpression();
+
+ @override
+ String transform() => "";
+}
+
+class MeiliAndOperatorExpression extends MeiliOperatorExpressionBase {
+ final List operands;
+
+ MeiliAndOperatorExpression({
+ required MeiliOperatorExpressionBase first,
+ required MeiliOperatorExpressionBase second,
+ }) : this.fromList([first, second]);
+
+ const MeiliAndOperatorExpression.fromList(this.operands);
+
+ @override
+ String transform() {
+ //space is mandatory
+ final filteredOperands = operands
+ .map((e) => e.transform())
+ .where((element) => element.isNotEmpty);
+ if (filteredOperands.isEmpty) {
+ return '';
+ } else if (filteredOperands.length == 1) {
+ return filteredOperands.first;
+ } else {
+ return filteredOperands.map((e) => '($e)').join(" AND ");
+ }
+ }
+
+ @override
+ bool operator ==(Object other) {
+ if (identical(this, other)) return true;
+
+ return other is MeiliAndOperatorExpression &&
+ _eqUnordered.equals(other.operands, operands);
+ }
+
+ @override
+ int get hashCode => Object.hash("AND", _eqUnordered.hash(operands));
+}
+
+class MeiliOrOperatorExpression extends MeiliOperatorExpressionBase {
+ final List operands;
+
+ MeiliOrOperatorExpression({
+ required MeiliOperatorExpressionBase first,
+ required MeiliOperatorExpressionBase second,
+ }) : this.fromList([first, second]);
+
+ const MeiliOrOperatorExpression.fromList(this.operands);
+
+ @override
+ String transform() {
+ final filteredOperands = operands
+ .map((e) => e.transform())
+ .where((element) => element.isNotEmpty);
+ if (filteredOperands.isEmpty) {
+ return '';
+ } else if (filteredOperands.length == 1) {
+ return filteredOperands.first;
+ } else {
+ return filteredOperands.map((e) => '($e)').join(" OR ");
+ }
+ }
+
+ @override
+ bool operator ==(Object other) {
+ if (identical(this, other)) return true;
+
+ return other is MeiliOrOperatorExpression &&
+ _eqUnordered.equals(other.operands, operands);
+ }
+
+ @override
+ int get hashCode => Object.hash("OR", _eqUnordered.hash(operands));
+}
+
+class MeiliToOperatorExpression extends MeiliOperatorExpressionBase {
+ final MeiliAttributeExpression attribute;
+ final MeiliValueExpressionBase min;
+ final MeiliValueExpressionBase max;
+
+ const MeiliToOperatorExpression({
+ required this.min,
+ required this.max,
+ required this.attribute,
+ });
+
+ @override
+ String transform() {
+ final attributeTransformed = attribute.transform();
+ return "$attributeTransformed ${min.transform()} TO $attributeTransformed ${max.transform()}";
+ }
+}
+
+class MeiliGeoRadiusOperatorExpression extends MeiliOperatorExpressionBase {
+ final MeiliPoint point;
+ final double distanceInMeters;
+
+ const MeiliGeoRadiusOperatorExpression(
+ this.point,
+ this.distanceInMeters,
+ );
+
+ @override
+ String transform() {
+ return '_geoRadius(${point.lat},${point.lng},$distanceInMeters)';
+ }
+}
+
+@RequiredMeiliServerVersion('1.1.0')
+class MeiliGeoBoundingBoxOperatorExpression
+ extends MeiliOperatorExpressionBase {
+ final MeiliPoint point1;
+ final MeiliPoint point2;
+
+ const MeiliGeoBoundingBoxOperatorExpression(
+ this.point1,
+ this.point2,
+ );
+
+ @override
+ String transform() {
+ return '_geoBoundingBox([${point1.lat},${point1.lng}],[${point2.lat},${point2.lng}])';
+ }
+}
+
+class MeiliExistsOperatorExpression extends MeiliOperatorExpressionBase {
+ final MeiliAttributeExpression attribute;
+
+ const MeiliExistsOperatorExpression(this.attribute);
+
+ @override
+ String transform() {
+ return "${attribute.transform()} EXISTS";
+ }
+}
+
+class MeiliNotExistsOperatorExpression extends MeiliOperatorExpressionBase {
+ final MeiliAttributeExpression attribute;
+
+ const MeiliNotExistsOperatorExpression(this.attribute);
+
+ @override
+ String transform() {
+ return "${attribute.transform()} NOT EXISTS";
+ }
+}
+
+@RequiredMeiliServerVersion('1.2.0')
+class MeiliIsNullOperatorExpression extends MeiliOperatorExpressionBase {
+ final MeiliAttributeExpression attribute;
+
+ const MeiliIsNullOperatorExpression(this.attribute);
+
+ @override
+ String transform() {
+ return "${attribute.transform()} IS NULL";
+ }
+}
+
+@RequiredMeiliServerVersion('1.2.0')
+class MeiliIsNotNullOperatorExpression extends MeiliOperatorExpressionBase {
+ final MeiliAttributeExpression attribute;
+
+ const MeiliIsNotNullOperatorExpression(this.attribute);
+
+ @override
+ String transform() {
+ return "${attribute.transform()} IS NOT NULL";
+ }
+}
+
+@RequiredMeiliServerVersion('1.2.0')
+class MeiliIsEmptyOperatorExpression extends MeiliOperatorExpressionBase {
+ final MeiliAttributeExpression attribute;
+
+ const MeiliIsEmptyOperatorExpression(this.attribute);
+
+ @override
+ String transform() {
+ return "${attribute.transform()} IS EMPTY";
+ }
+}
+
+@RequiredMeiliServerVersion('1.2.0')
+class MeiliIsNotEmptyOperatorExpression extends MeiliOperatorExpressionBase {
+ final MeiliAttributeExpression attribute;
+
+ const MeiliIsNotEmptyOperatorExpression(this.attribute);
+
+ @override
+ String transform() {
+ return "${attribute.transform()} IS NOT EMPTY";
+ }
+}
+
+class MeiliNotOperatorExpression extends MeiliOperatorExpressionBase {
+ final MeiliOperatorExpressionBase operator;
+
+ const MeiliNotOperatorExpression(this.operator)
+ : assert(operator is! MeiliEmptyExpression,
+ "Cannot negate (NOT) an empty operator");
+
+ @override
+ String transform() {
+ return "NOT ${operator.transform()}";
+ }
+}
+
+class MeiliInOperatorExpression extends MeiliOperatorExpressionBase {
+ final MeiliAttributeExpression attribute;
+ final List values;
+
+ const MeiliInOperatorExpression({
+ required this.attribute,
+ required this.values,
+ });
+
+ @override
+ String transform() {
+ //TODO(ahmednfwela): escape commas in values ?
+ return "${attribute.transform()} IN [${values.map((e) => e.transform()).join(',')}]";
+ }
+}
+
+/// Represents an operator that has a value as an operand
+abstract class MeiliValueOperandOperatorExpressionBase
+ extends MeiliOperatorExpressionBase {
+ final MeiliAttributeExpression property;
+ final MeiliValueExpressionBase value;
+
+ const MeiliValueOperandOperatorExpressionBase({
+ required this.property,
+ required this.value,
+ });
+
+ String get operator;
+
+ @override
+ String transform() {
+ return '${property.transform()} $operator ${value.transform()}';
+ }
+}
+
+class MeiliEqualsOperatorExpression
+ extends MeiliValueOperandOperatorExpressionBase {
+ const MeiliEqualsOperatorExpression({
+ required super.property,
+ required super.value,
+ });
+
+ @override
+ final String operator = "=";
+}
+
+class MeiliNotEqualsOperatorExpression
+ extends MeiliValueOperandOperatorExpressionBase {
+ const MeiliNotEqualsOperatorExpression({
+ required super.property,
+ required super.value,
+ });
+
+ @override
+ final String operator = "!=";
+}
+
+class MeiliGreaterThanOperatorExpression
+ extends MeiliValueOperandOperatorExpressionBase {
+ const MeiliGreaterThanOperatorExpression({
+ required super.property,
+ required super.value,
+ });
+
+ @override
+ final String operator = ">";
+}
+
+class MeiliGreaterThanEqualsOperatorExpression
+ extends MeiliValueOperandOperatorExpressionBase {
+ const MeiliGreaterThanEqualsOperatorExpression({
+ required super.property,
+ required super.value,
+ });
+
+ @override
+ final String operator = ">=";
+}
+
+class MeiliLessThanOperatorExpression
+ extends MeiliValueOperandOperatorExpressionBase {
+ const MeiliLessThanOperatorExpression({
+ required super.property,
+ required super.value,
+ });
+
+ @override
+ final String operator = "<";
+}
+
+class MeiliLessThanEqualsOperatorExpression
+ extends MeiliValueOperandOperatorExpressionBase {
+ const MeiliLessThanEqualsOperatorExpression({
+ required super.property,
+ required super.value,
+ });
+
+ @override
+ final String operator = "<=";
+}
diff --git a/lib/src/filter_builder/values.dart b/lib/src/filter_builder/values.dart
index c1a8a19f..db1f6d42 100644
--- a/lib/src/filter_builder/values.dart
+++ b/lib/src/filter_builder/values.dart
@@ -29,8 +29,10 @@ class MeiliDateTimeValueExpression extends MeiliValueExpressionBase {
"DateTime passed to Meili must be in UTC to avoid inconsistency accross multiple devices",
);
+ /// Unix epoch time is seconds since epoch
@override
- String transform() => value.millisecondsSinceEpoch.toString();
+ String transform() =>
+ (value.millisecondsSinceEpoch / 1000).floor().toString();
@override
bool operator ==(Object other) {
diff --git a/lib/src/tenant_token/exceptions.dart b/lib/src/tenant_token/exceptions.dart
index 53acbb35..e3cefd0a 100644
--- a/lib/src/tenant_token/exceptions.dart
+++ b/lib/src/tenant_token/exceptions.dart
@@ -1,4 +1,4 @@
-part of tenant_token;
+part of '../tenant_token.dart';
class ExpiredSignatureException implements Exception {
const ExpiredSignatureException();
diff --git a/lib/src/tenant_token/generator.dart b/lib/src/tenant_token/generator.dart
index 2e9802c0..c0771039 100644
--- a/lib/src/tenant_token/generator.dart
+++ b/lib/src/tenant_token/generator.dart
@@ -1,4 +1,4 @@
-part of tenant_token;
+part of '../tenant_token.dart';
final _jsonEncoder = json.fuse(utf8.fuse(base64Url));
diff --git a/lib/src/version.dart b/lib/src/version.dart
index 84e9c1de..519bf9f7 100644
--- a/lib/src/version.dart
+++ b/lib/src/version.dart
@@ -1,5 +1,5 @@
class Version {
- static const String current = '0.14.0';
+ static const String current = '0.15.0';
static String get qualifiedVersion {
return "Meilisearch Dart (v$current)";
diff --git a/pubspec.yaml b/pubspec.yaml
index d295d3ee..5dbe7b7b 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,6 +1,6 @@
name: meilisearch
description: Meilisearch Dart is the Meilisearch API client for Dart and Flutter developers.
-version: 0.14.0
+version: 0.15.0
homepage: https://meilisearch.com
repository: https://github.com/meilisearch/meilisearch-dart
issue_tracker: https://github.com/meilisearch/meilisearch-dart/issues
@@ -17,8 +17,8 @@ dependencies:
dev_dependencies:
test: ^1.0.0
- dart_jsonwebtoken: ^2.3.2
- lints: ^2.1.0
+ dart_jsonwebtoken: ^2.12.2
+ lints: ">=2.1.0 <4.0.0"
json_serializable: ^6.7.1
build_runner: ^2.4.6
diff --git a/test/code_samples.dart b/test/code_samples.dart
new file mode 100644
index 00000000..3de892be
--- /dev/null
+++ b/test/code_samples.dart
@@ -0,0 +1,888 @@
+// ignore_for_file: unused_element
+
+import 'dart:io';
+
+import 'package:meilisearch/meilisearch.dart';
+import 'package:test/test.dart';
+
+import 'utils/client.dart';
+
+void main() {
+ // this file hosts some code samples referenced in
+ // .code-samples.meilisearch.yaml
+ // it's subject to tests, lint rules, deprecation notices, etc...
+ group('code samples', () {
+ setUpClient();
+
+ test('excerpts', () async {
+ void a1() async {
+ // #docregion typo_tolerance_guide_1
+ final toUpdate = TypoTolerance(enabled: false);
+ await client.index('movies').updateTypoTolerance(toUpdate);
+ // #enddocregion
+ }
+
+ void a2() async {
+ // #docregion typo_tolerance_guide_2
+ final toUpdate = TypoTolerance(
+ disableOnAttributes: ['title'],
+ );
+ await client.index('movies').updateTypoTolerance(toUpdate);
+ // #enddocregion
+ }
+
+ void a3() async {
+ // #docregion typo_tolerance_guide_3
+ final toUpdate = TypoTolerance(
+ disableOnWords: ['shrek'],
+ );
+ await client.index('movies').updateTypoTolerance(toUpdate);
+ // #enddocregion
+ }
+
+ void a4() async {
+ // #docregion typo_tolerance_guide_4
+ final toUpdate = TypoTolerance(
+ minWordSizeForTypos: MinWordSizeForTypos(
+ oneTypo: 4,
+ twoTypos: 10,
+ ),
+ );
+ await client.index('movies').updateTypoTolerance(toUpdate);
+ // #enddocregion
+ }
+
+ void a8() async {
+ // #docregion getting_started_add_meteorites
+ final json = await File('meteorites.json').readAsString();
+
+ await client.index('meteorites').addDocumentsJson(json);
+ // #enddocregion
+ }
+
+ void a10() async {
+ // #docregion add_movies_json_1
+ // import 'dart:io';
+ // import 'dart:convert';
+ final json = await File('movies.json').readAsString();
+ await client.index('movies').addDocumentsJson(json);
+ // #enddocregion
+ }
+
+ void a11() async {
+ // #docregion security_guide_delete_key_1
+ var client = MeiliSearchClient('http://localhost:7700', 'masterKey');
+ await client.deleteKey('ac5cd97d-5a4b-4226-a868-2d0eb6d197ab');
+ // #enddocregion
+ }
+
+ void a12() async {
+ // #docregion security_guide_list_keys_1
+ var client = MeiliSearchClient('http://localhost:7700', 'masterKey');
+ await client.getKeys();
+ // #enddocregion
+ }
+
+ void a13() async {
+ // #docregion security_guide_create_key_1
+ var client = MeiliSearchClient('http://localhost:7700', 'masterKey');
+ await client.createKey(
+ description: 'Search patient records key',
+ actions: ['search'],
+ indexes: ['patient_medical_records'],
+ expiresAt: DateTime(2023, 01, 01),
+ );
+ // #enddocregion
+ }
+
+ void a14() async {
+ // #docregion authorization_header_1
+ var client = MeiliSearchClient('http://localhost:7700', 'masterKey');
+ await client.getKeys();
+ // #enddocregion
+ }
+
+ void a15() async {
+ // #docregion security_guide_search_key_1
+ var client = MeiliSearchClient('http://localhost:7700', 'apiKey');
+ await client.index('patient_medical_records').search('');
+ // #enddocregion
+ }
+
+ void a16() async {
+ // #docregion security_guide_update_key_1
+ var client = MeiliSearchClient('http://localhost:7700', 'masterKey');
+ await client.updateKey(
+ '74c9c733-3368-4738-bbe5-1d18a5fecb37',
+ description: 'Default Search API Key',
+ );
+ // #enddocregion
+ }
+
+ // #docregion date_guide_index_1
+ //import 'dart:io';
+ //import 'dart:convert';
+
+ final json = await File('games.json').readAsString();
+
+ await client.index('games').addDocumentsJson(json);
+ // #enddocregion
+
+ // #docregion date_guide_filterable_attributes_1
+ await client
+ .index('games')
+ .updateFilterableAttributes(['release_timestamp']);
+ // #enddocregion
+
+ // #docregion date_guide_filter_1
+ await client.index('games').search(
+ '',
+ SearchQuery(
+ filterExpression: Meili.and([
+ Meili.gte(
+ 'release_timestamp'.toMeiliAttribute(),
+ Meili.value(DateTime(2017, 12, 31, 23, 0)),
+ ),
+ Meili.lt(
+ 'release_timestamp'.toMeiliAttribute(),
+ Meili.value(DateTime(2022, 12, 31, 23, 0)),
+ ),
+ ]),
+ ),
+ );
+ // #enddocregion
+
+ // #docregion date_guide_sortable_attributes_1
+ await client
+ .index('games')
+ .updateSortableAttributes(['release_timestamp']);
+ // #enddocregion
+
+ // #docregion date_guide_sort_1
+ await client
+ .index('games')
+ .search('', SearchQuery(sort: ['release_timestamp:desc']));
+ // #enddocregion
+
+ // #docregion get_all_tasks_paginating_1
+ await client.getTasks(params: TasksQuery(limit: 2, from: 10));
+ // #enddocregion
+
+ // #docregion get_all_tasks_paginating_2
+ await client.getTasks(params: TasksQuery(limit: 2, from: 8));
+ // #enddocregion
+
+ // #docregion get_pagination_settings_1
+ await client.index('movies').getPagination();
+ // #enddocregion
+
+ // #docregion update_pagination_settings_1
+ await client
+ .index('books')
+ .updatePagination(Pagination(maxTotalHits: 100));
+ // #enddocregion
+
+ // #docregion reset_pagination_settings_1
+ await client.index('movies').resetPagination();
+ // #enddocregion
+
+ // #docregion get_faceting_settings_1
+ await client.index('movies').getFaceting();
+ // #enddocregion
+
+ // #docregion update_faceting_settings_1
+ await client.index('books').updateFaceting(Faceting(
+ maxValuesPerFacet: 2,
+ sortFacetValuesBy: {
+ '*': FacetingSortTypes.alpha,
+ 'genres': FacetingSortTypes.count
+ }));
+ // #enddocregion
+
+ // #docregion reset_faceting_settings_1
+ await client.index('movies').resetFaceting();
+ // #enddocregion
+
+ // #docregion get_one_index_1
+ await client.getIndex('movies');
+ // #enddocregion
+
+ // #docregion list_all_indexes_1
+ await client.getIndexes(params: IndexesQuery(limit: 3));
+ // #enddocregion
+
+ // #docregion create_an_index_1
+ await client.createIndex('movies', primaryKey: 'id');
+ // #enddocregion
+
+ // #docregion update_an_index_1
+ await client.index('movies').update(primaryKey: 'id');
+ // #enddocregion
+
+ // #docregion delete_an_index_1
+ await client.index('movies').delete();
+ // #enddocregion
+
+ // #docregion get_one_document_1
+ await client.index('movies').getDocument(25684,
+ fields: ['id', 'title', 'poster', 'release_date']);
+ // #enddocregion
+
+ // #docregion add_or_replace_documents_1
+ await client.index('movies').addDocuments([
+ {
+ 'id': 287947,
+ 'title': 'Shazam',
+ 'poster':
+ 'https://image.tmdb.org/t/p/w1280/xnopI5Xtky18MPhK40cZAGAOVeV.jpg',
+ 'overview':
+ 'A boy is given the ability to become an adult superhero in times of need with a single magic word.',
+ 'release_date': '2019-03-23'
+ }
+ ]);
+ // #enddocregion
+
+ // #docregion add_or_update_documents_1
+ await client.index('movies').updateDocuments([
+ {
+ 'id': 287947,
+ 'title': 'Shazam ⚡️',
+ 'genres': 'comedy',
+ }
+ ]);
+ // #enddocregion
+
+ // #docregion delete_all_documents_1
+ await client.index('movies').deleteAllDocuments();
+ // #enddocregion
+
+ // #docregion delete_one_document_1
+ await client.index('movies').deleteDocument(25684);
+ // #enddocregion
+
+ // #docregion delete_documents_by_batch_1
+ await client.index('movies').deleteDocuments(
+ DeleteDocumentsQuery(
+ ids: [23488, 153738, 437035, 363869],
+ ),
+ );
+ // #enddocregion
+
+ // #docregion search_post_1
+ await client.index('movies').search('American ninja');
+ // #enddocregion
+
+ // #docregion get_task_1
+ await client.getTask(1);
+ // #enddocregion
+
+ // #docregion get_all_tasks_1
+ await client.getTasks();
+ // #enddocregion
+
+ // #docregion get_settings_1
+ await client.index('movies').getSettings();
+ // #enddocregion
+
+ // #docregion update_settings_1
+ await client.index('movies').updateSettings(
+ IndexSettings(
+ rankingRules: [
+ 'words',
+ 'typo',
+ 'proximity',
+ 'attribute',
+ 'sort',
+ 'exactness',
+ 'release_date:desc',
+ 'rank:desc'
+ ],
+ distinctAttribute: 'movie_id',
+ searchableAttributes: ['title', 'overview', 'genres'],
+ displayedAttributes: [
+ 'title',
+ 'overview',
+ 'genres',
+ 'release_date'
+ ],
+ stopWords: ['the', 'a', 'an'],
+ sortableAttributes: ['title', 'release_date'],
+ synonyms: {
+ 'wolverine': ['xmen', 'logan'],
+ 'logan': ['wolverine'],
+ },
+ ),
+ );
+ // #enddocregion
+
+ // #docregion reset_settings_1
+ await client.index('movies').resetSettings();
+ // #enddocregion
+
+ // #docregion get_synonyms_1
+ await client.index('movies').getSynonyms();
+ // #enddocregion
+
+ // #docregion update_synonyms_1
+ await client.index('movies').updateSynonyms({
+ 'wolverine': ['xmen', 'logan'],
+ 'logan': ['wolverine', 'xmen'],
+ 'wow': ['world of warcraft'],
+ });
+ // #enddocregion
+
+ // #docregion reset_synonyms_1
+ await client.index('movies').resetSynonyms();
+ // #enddocregion
+
+ // #docregion get_stop_words_1
+ await client.index('movies').getStopWords();
+ // #enddocregion
+
+ // #docregion update_stop_words_1
+ await client.index('movies').updateStopWords(['of', 'the', 'to']);
+ // #enddocregion
+
+ // #docregion reset_stop_words_1
+ await client.index('movies').resetStopWords();
+ // #enddocregion
+
+ // #docregion get_ranking_rules_1
+ await client.index('movies').getRankingRules();
+ // #enddocregion
+
+ // #docregion update_ranking_rules_1
+ await client.index('movies').updateRankingRules([
+ 'words',
+ 'typo',
+ 'proximity',
+ 'attribute',
+ 'sort',
+ 'exactness',
+ 'release_date:asc',
+ 'rank:desc',
+ ]);
+ // #enddocregion
+
+ // #docregion reset_ranking_rules_1
+ await client.index('movies').resetRankingRules();
+ // #enddocregion
+
+ // #docregion get_distinct_attribute_1
+ await client.index('shoes').getDistinctAttribute();
+ // #enddocregion
+
+ // #docregion update_distinct_attribute_1
+ await client.index('shoes').updateDistinctAttribute('skuid');
+ // #enddocregion
+
+ // #docregion reset_distinct_attribute_1
+ await client.index('shoes').resetDistinctAttribute();
+ // #enddocregion
+
+ // #docregion get_filterable_attributes_1
+ await client.index('movies').getFilterableAttributes();
+ // #enddocregion
+
+ // #docregion update_filterable_attributes_1
+ await client
+ .index('movies')
+ .updateFilterableAttributes(['genres', 'director']);
+ // #enddocregion
+
+ // #docregion reset_filterable_attributes_1
+ await client.index('movies').resetFilterableAttributes();
+ // #enddocregion
+
+ // #docregion get_searchable_attributes_1
+ await client.index('movies').getSearchableAttributes();
+ // #enddocregion
+
+ // #docregion update_searchable_attributes_1
+ await client
+ .index('movies')
+ .updateSearchableAttributes(['title', 'overview', 'genres']);
+ // #enddocregion
+
+ // #docregion reset_searchable_attributes_1
+ await client.index('movies').resetSearchableAttributes();
+ // #enddocregion
+
+ // #docregion get_displayed_attributes_1
+ await client.index('movies').getDisplayedAttributes();
+ // #enddocregion
+
+ // #docregion update_displayed_attributes_1
+ await client.index('movies').updateDisplayedAttributes([
+ 'title',
+ 'overview',
+ 'genres',
+ 'release_date',
+ ]);
+ // #enddocregion
+
+ // #docregion reset_displayed_attributes_1
+ await client.index('movies').resetDisplayedAttributes();
+ // #enddocregion
+
+ // #docregion get_typo_tolerance_1
+ await client.index('books').getTypoTolerance();
+ // #enddocregion
+
+ // #docregion update_typo_tolerance_1
+ final toUpdate = TypoTolerance(
+ minWordSizeForTypos: MinWordSizeForTypos(
+ oneTypo: 4,
+ twoTypos: 10,
+ ),
+ disableOnAttributes: ['title'],
+ );
+ await client.index('books').updateTypoTolerance(toUpdate);
+ // #enddocregion
+
+ // #docregion reset_typo_tolerance_1
+ await client.index('books').resetTypoTolerance();
+ // #enddocregion
+
+ // #docregion get_index_stats_1
+ await client.index('movies').getStats();
+ // #enddocregion
+
+ // #docregion get_indexes_stats_1
+ await client.getStats();
+ // #enddocregion
+
+ // #docregion get_health_1
+ await client.health();
+ // #enddocregion
+
+ // #docregion get_version_1
+ await client.getVersion();
+ // #enddocregion
+
+ // #docregion distinct_attribute_guide_1
+ await client.index('jackets').updateDistinctAttribute('product_id');
+ // #enddocregion
+
+ // #docregion field_properties_guide_searchable_1
+ await client
+ .index('movies')
+ .updateSearchableAttributes(['title', 'overview', 'genres']);
+ // #enddocregion
+
+ // #docregion field_properties_guide_displayed_1
+ await client.index('movies').updateDisplayedAttributes([
+ 'title',
+ 'overview',
+ 'genres',
+ 'release_date',
+ ]);
+ // #enddocregion
+
+ // #docregion filtering_guide_1
+ await client.index('movie_ratings').search(
+ 'Avengers',
+ SearchQuery(
+ filterExpression: Meili.gt(
+ Meili.attr('release_date'),
+ DateTime.utc(1995, 3, 18).toMeiliValue(),
+ ),
+ ),
+ );
+ // #enddocregion
+
+ // #docregion filtering_guide_2
+ await client.index('movie_ratings').search(
+ 'Batman',
+ SearchQuery(
+ filterExpression: Meili.and([
+ Meili.attr('release_date')
+ .gt(DateTime.utc(1995, 3, 18).toMeiliValue()),
+ Meili.or([
+ 'director'.toMeiliAttribute().eq('Tim Burton'.toMeiliValue()),
+ 'director'
+ .toMeiliAttribute()
+ .eq('Christopher Nolan'.toMeiliValue()),
+ ]),
+ ]),
+ ),
+ );
+ // #enddocregion
+
+ // #docregion filtering_guide_3
+ await client.index('movie_ratings').search(
+ 'Planet of the Apes',
+ SearchQuery(
+ filterExpression: Meili.and([
+ Meili.attr('release_date')
+ .gt(DateTime.utc(2020, 1, 1, 13, 15, 50).toMeiliValue()),
+ Meili.not(
+ Meili.attr('director').eq("Tim Burton".toMeiliValue()),
+ ),
+ ]),
+ ),
+ );
+ // #enddocregion
+
+ // #docregion search_parameter_guide_query_1
+ await client.index('movies').search('shifu');
+ // #enddocregion
+
+ // #docregion search_parameter_guide_offset_1
+ await client.index('movies').search('shifu', SearchQuery(offset: 1));
+ // #enddocregion
+
+ // #docregion search_parameter_guide_limit_1
+ await client.index('movies').search('shifu', SearchQuery(limit: 2));
+ // #enddocregion
+
+ // #docregion search_parameter_guide_matching_strategy_1
+ await client.index('movies').search(
+ 'big fat liar', SearchQuery(matchingStrategy: MatchingStrategy.last));
+ // #enddocregion
+
+ // #docregion search_parameter_guide_matching_strategy_2
+ await client.index('movies').search(
+ 'big fat liar', SearchQuery(matchingStrategy: MatchingStrategy.all));
+ // #enddocregion
+
+ // #docregion search_parameter_guide_retrieve_1
+ await client.index('movies').search(
+ 'shifu', SearchQuery(attributesToRetrieve: ['overview', 'title']));
+ // #enddocregion
+
+ // #docregion search_parameter_guide_crop_1
+ await client.index('movies').search(
+ 'shifu', SearchQuery(attributesToCrop: ['overview'], cropLength: 5));
+ // #enddocregion
+
+ // #docregion search_parameter_guide_highlight_1
+ await client.index('movies').search(
+ 'winter feast', SearchQuery(attributesToHighlight: ['overview']));
+ // #enddocregion
+
+ // #docregion search_parameter_guide_show_matches_position_1
+ await client
+ .index('movies')
+ .search('winter feast', SearchQuery(showMatchesPosition: true));
+ // #enddocregion
+
+ // #docregion primary_field_guide_create_index_primary_key
+ await client.createIndex('books', primaryKey: 'reference_number');
+ // #enddocregion
+
+ // #docregion primary_field_guide_update_document_primary_key
+ await client.updateIndex('books', 'title');
+ // #enddocregion
+
+ // #docregion primary_field_guide_add_document_primary_key
+ await client.index('movies').addDocuments([
+ {
+ 'reference_number': 287947,
+ 'title': 'Diary of a Wimpy Kid',
+ 'author': 'Jeff Kinney',
+ 'genres': ['comedy', 'humor'],
+ 'price': 5.00
+ }
+ ], primaryKey: 'reference_number');
+ // #enddocregion
+
+ // #docregion getting_started_update_ranking_rules
+ await client.index('movies').updateRankingRules([
+ 'exactness',
+ 'words',
+ 'typo',
+ 'proximity',
+ 'attribute',
+ 'sort',
+ 'release_date:asc',
+ 'rank:desc',
+ ]);
+ // #enddocregion
+
+ // #docregion getting_started_update_searchable_attributes
+ await client.index('movies').updateSearchableAttributes(['title']);
+ // #enddocregion
+
+ // #docregion getting_started_update_stop_words
+ await client.index('movies').updateStopWords(['the']);
+ // #enddocregion
+
+ // #docregion getting_started_check_task_status
+ await client.getTask(0);
+ // #enddocregion
+
+ // #docregion getting_started_synonyms
+ await client.index('movies').updateSynonyms({
+ 'winnie': ['piglet'],
+ 'piglet': ['winnie'],
+ });
+ // #enddocregion
+
+ // #docregion getting_started_update_displayed_attributes
+ await client
+ .index('movies')
+ .updateDisplayedAttributes(['title', 'overview', 'poster']);
+ // #enddocregion
+
+ // #docregion getting_started_configure_settings
+ await client.index('meteorites').updateSettings(IndexSettings(
+ filterableAttributes: ['mass', '_geo'],
+ sortableAttributes: ['mass', '_geo']));
+ // #enddocregion
+
+ // #docregion getting_started_geo_radius
+ await client.index('meteorites').search(
+ '',
+ SearchQuery(
+ filterExpression: Meili.geoRadius(
+ (lat: 46.9480, lng: 7.4474),
+ 210000,
+ ),
+ ),
+ );
+ // #enddocregion
+
+ // #docregion getting_started_geo_point
+ await client.index('meteorites').search(
+ '', SearchQuery(sort: ['_geoPoint(48.8583701, 2.2922926):asc']));
+ // #enddocregion
+
+ // #docregion getting_started_sorting
+ await client.index('meteorites').search(
+ '',
+ SearchQuery(
+ sort: ['mass:asc'],
+ filterExpression: Meili.attr('mass').lt(200.toMeiliValue()),
+ ),
+ );
+ // #enddocregion
+
+ // #docregion getting_started_filtering
+ await client
+ .index('meteorites')
+ .search('', SearchQuery(filter: 'mass < 200'));
+ // #enddocregion
+
+ // #docregion getting_started_faceting
+ await client.index('books').updateFaceting(Faceting(
+ maxValuesPerFacet: 2,
+ sortFacetValuesBy: {'*': FacetingSortTypes.count}));
+ // #enddocregion
+
+ void a9() async {
+ // #docregion getting_started_typo_tolerance
+ final toUpdate = TypoTolerance(
+ minWordSizeForTypos: MinWordSizeForTypos(oneTypo: 4),
+ );
+ await client.index('movies').updateTypoTolerance(toUpdate);
+ // #enddocregion
+ }
+
+ // #docregion getting_started_pagination
+ await client
+ .index('books')
+ .updatePagination(Pagination(maxTotalHits: 500));
+ // #enddocregion
+
+ // #docregion filtering_update_settings_1
+ await client.index('movies').updateFilterableAttributes([
+ 'director',
+ 'genres',
+ ]);
+ // #enddocregion
+
+ // #docregion faceted_search_walkthrough_filter_1
+ await client.index('movies').search(
+ 'thriller',
+ SearchQuery(filter: [
+ ['genres = Horror', 'genres = Mystery'],
+ 'director = "Jordan Peele"'
+ ]));
+ // #enddocregion
+
+ // #docregion post_dump_1
+ await client.createDump();
+ // #enddocregion
+
+ // #docregion phrase_search_1
+ await client.index('movies').search('"african american" horror');
+ // #enddocregion
+
+ // #docregion sorting_guide_update_sortable_attributes_1
+ await client.index('books').updateSortableAttributes(['author', 'price']);
+ // #enddocregion
+
+ // #docregion sorting_guide_update_ranking_rules_1
+ await client.index('books').updateRankingRules(
+ ['words', 'sort', 'typo', 'proximity', 'attribute', 'exactness']);
+ // #enddocregion
+
+ // #docregion sorting_guide_sort_parameter_1
+ await client
+ .index('books')
+ .search('science fiction', SearchQuery(sort: ['price:asc']));
+ // #enddocregion
+
+ // #docregion sorting_guide_sort_parameter_2
+ await client
+ .index('books')
+ .search('butler', SearchQuery(sort: ['author:desc']));
+ // #enddocregion
+
+ // #docregion get_sortable_attributes_1
+ await client.index('books').getSortableAttributes();
+ // #enddocregion
+
+ // #docregion update_sortable_attributes_1
+ await client.index('books').updateSortableAttributes(['price', 'author']);
+ // #enddocregion
+
+ // #docregion reset_sortable_attributes_1
+ await client.index('books').resetSortableAttributes();
+ // #enddocregion
+
+ // #docregion search_parameter_guide_sort_1
+ await client
+ .index('books')
+ .search('science fiction', SearchQuery(sort: ['price:asc']));
+ // #enddocregion
+
+ // #docregion geosearch_guide_filter_settings_1
+ await client.index('restaurants').updateFilterableAttributes(['_geo']);
+ // #enddocregion
+
+ // #docregion geosearch_guide_filter_usage_1
+ await client.index('restaurants').search(
+ '',
+ SearchQuery(
+ filterExpression: Meili.geoRadius(
+ (lat: 45.472735, lng: 9.184019),
+ 2000,
+ ),
+ ),
+ );
+ // #enddocregion
+
+ // #docregion geosearch_guide_filter_usage_2
+ await client.index('restaurants').search(
+ '',
+ SearchQuery(
+ filterExpression: Meili.and([
+ Meili.geoRadius(
+ (lat: 45.472735, lng: 9.184019),
+ 2000,
+ ),
+ Meili.attr('type').eq('pizza'.toMeiliValue())
+ ]),
+ ),
+ );
+ // #enddocregion
+
+ // #docregion geosearch_guide_sort_settings_1
+ await client.index('restaurants').updateSortableAttributes(['_geo']);
+ // #enddocregion
+
+ // #docregion geosearch_guide_sort_usage_1
+ await client.index('restaurants').search(
+ '', SearchQuery(sort: ['_geoPoint(48.8561446, 2.2978204):asc']));
+ // #enddocregion
+
+ // #docregion geosearch_guide_sort_usage_2
+ await client.index('restaurants').search(
+ '',
+ SearchQuery(
+ sort: ['_geoPoint(48.8561446, 2.2978204):asc', 'rating:desc']));
+ // #enddocregion
+
+ // #docregion get_one_key_1
+ await client.getKey('6062abda-a5aa-4414-ac91-ecd7944c0f8d');
+ // #enddocregion
+
+ // #docregion get_all_keys_1
+ await client.getKeys(params: KeysQuery(limit: 3));
+ // #enddocregion
+
+ // #docregion create_a_key_1
+ await client.createKey(
+ description: 'Add documents: Products API key',
+ actions: ['documents.add'],
+ indexes: ['products'],
+ expiresAt: DateTime(2042, 04, 02));
+ // #enddocregion
+
+ // #docregion update_a_key_1
+ await client.updateKey(
+ '6062abda-a5aa-4414-ac91-ecd7944c0f8d',
+ description: 'Manage documents: Products/Reviews API key',
+ name: 'Products/Reviews API key',
+ );
+ // #enddocregion
+
+ // #docregion delete_a_key_1
+ await client.deleteKey('6062abda-a5aa-4414-ac91-ecd7944c0f8d');
+ // #enddocregion
+
+ // #docregion search_parameter_guide_crop_marker_1
+ await client.index('movies').search(
+ 'shifu',
+ SearchQuery(
+ attributesToCrop: ['overview'],
+ cropMarker: '[…]',
+ ),
+ );
+ // #enddocregion
+
+ // #docregion search_parameter_guide_highlight_tag_1
+ await client.index('movies').search(
+ 'winter feast',
+ SearchQuery(
+ attributesToHighlight: ['overview'],
+ highlightPreTag: '',
+ highlightPostTag: '',
+ ),
+ );
+ // #enddocregion
+
+ // #docregion geosearch_guide_filter_usage_3
+ await client.index('restaurants').search(
+ '',
+ SearchQuery(
+ filter:
+ '_geoBoundingBox([45.494181, 9.214024], [45.449484, 9.179175])'));
+ });
+ // #enddocregion
+ // skip this test, since it's only used for generating code samples
+ }, skip: true);
+
+// unformatted examples
+/*
+ // #docregion getting_started_search_md
+ ```dart
+ await client.index('movies').search('botman');
+ ```
+
+ [About this SDK](https://github.com/meilisearch/meilisearch-dart/)
+ // #enddocregion
+
+ // #docregion getting_started_add_documents_md
+ ```bash
+ dart pub add meilisearch
+ ```
+
+ ```dart
+ import 'package:meilisearch/meilisearch.dart';
+ import 'dart:io';
+ import 'dart:convert';
+
+ var client = MeiliSearchClient('http://localhost:7700', 'aSampleMasterKey');
+
+ final json = await File('movies.json').readAsString();
+
+ await client.index('movies').addDocumentsJson(json);
+ ```
+
+ [About this SDK](https://github.com/meilisearch/meilisearch-dart/)
+ // #enddocregion
+*/
+}
diff --git a/test/documents_test.dart b/test/documents_test.dart
index b0c7a8ee..8023a8f1 100644
--- a/test/documents_test.dart
+++ b/test/documents_test.dart
@@ -557,4 +557,49 @@ void main() {
});
});
});
+
+ test(
+ 'documents code samples',
+ () async {
+ // #docregion delete_documents_by_filter_1
+ await client.index('movies').deleteDocuments(
+ DeleteDocumentsQuery(
+ filterExpression: Meili.or([
+ Meili.attr('genres').eq(Meili.value('action')),
+ Meili.attr('genres').eq(Meili.value('adventure')),
+ ]),
+ ),
+ );
+ // #enddocregion
+
+ // #docregion get_documents_1
+ await client.index('movies').getDocuments(
+ params: DocumentsQuery(
+ limit: 2,
+ filter: Meili.attr('genres').eq('action'.toMeiliValue()),
+ ),
+ );
+ // #enddocregion
+
+ // #docregion get_documents_post_1
+ await client.index('movies').getDocuments(
+ params: DocumentsQuery(
+ filterExpression: Meili.and([
+ 'language'.toMeiliAttribute().eq('English'.toMeiliValue()),
+ Meili.and([
+ 'rating'.toMeiliAttribute().gt(3.toMeiliValue()),
+ Meili.or([
+ 'genres'.toMeiliAttribute().eq('Adventure'.toMeiliValue()),
+ 'genres'.toMeiliAttribute().eq('Fiction'.toMeiliValue()),
+ ]),
+ ]),
+ ]),
+ fields: ['title', 'genres', 'rating', 'language'],
+ limit: 3,
+ ),
+ );
+ // #enddocregion
+ },
+ skip: true,
+ );
}
diff --git a/test/exceptions_test.dart b/test/exceptions_test.dart
index 3981a7d1..6975cbff 100644
--- a/test/exceptions_test.dart
+++ b/test/exceptions_test.dart
@@ -25,7 +25,7 @@ void main() {
throwsA(isA().having(
(error) => error.toString(), // Actual
'toString() method', // Description of the check
- 'MeiliSearchApiError - message: The request returned an invalid status code of 404.', // Expected
+ contains('404'), // Expected
)),
);
});
diff --git a/test/filter_builder_test.dart b/test/filter_builder_test.dart
index 86431fce..fe962c83 100644
--- a/test/filter_builder_test.dart
+++ b/test/filter_builder_test.dart
@@ -75,7 +75,7 @@ void main() {
});
test("Dates", () {
final testData = [
- [DateTime.utc(1999, 12, 14, 18, 53, 56), '945197636000'],
+ [DateTime.utc(1999, 12, 14, 18, 53, 56), '945197636'],
];
for (var element in testData) {
diff --git a/test/models/test_client.dart b/test/models/test_client.dart
index a4014528..5f7a036d 100644
--- a/test/models/test_client.dart
+++ b/test/models/test_client.dart
@@ -1,144 +1,130 @@
-import 'package:collection/collection.dart';
-import 'package:dio/dio.dart';
-import 'package:meilisearch/meilisearch.dart';
-
-class TestMeiliSearchClient extends MeiliSearchClient {
- TestMeiliSearchClient(
- String serverUrl, [
- String? apiKey,
- Duration? connectTimeout,
- HttpClientAdapter? adapter,
- List? interceptors,
- ]) : super(
- serverUrl,
- apiKey,
- connectTimeout,
- adapter,
- interceptors,
- );
-
- factory TestMeiliSearchClient.withCustomDio(
- String serverUrl, {
- String? apiKey,
- Duration? connectTimeout,
- HttpClientAdapter? adapter,
- List? interceptors,
- }) =>
- TestMeiliSearchClient(
- serverUrl,
- apiKey,
- connectTimeout,
- adapter,
- interceptors,
- );
-
- final usedIndexes = {};
- final usedKeys = {};
-
- @override
- MeiliSearchIndex index(String uid, {bool deleteWhenDone = true}) {
- if (deleteWhenDone) {
- usedIndexes.add(uid);
- }
- return super.index(uid);
- }
-
- @override
- Future createIndex(String uid, {String? primaryKey}) {
- usedIndexes.add(uid);
- return super.createIndex(uid, primaryKey: primaryKey);
- }
-
- @override
- Future deleteIndex(String uid) {
- usedIndexes.remove(uid);
- return super.deleteIndex(uid);
- }
-
- @override
- Future