From b726fe5c4ef19d8c71f2a7317539161e369e5619 Mon Sep 17 00:00:00 2001 From: Louis Dureuil Date: Mon, 27 Feb 2023 16:01:27 +0100 Subject: [PATCH 01/15] Add multi-search spec --- text/0192-multi-search-api.md | 70 +++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 text/0192-multi-search-api.md diff --git a/text/0192-multi-search-api.md b/text/0192-multi-search-api.md new file mode 100644 index 00000000..f37bad48 --- /dev/null +++ b/text/0192-multi-search-api.md @@ -0,0 +1,70 @@ +# Multi-search API + +## 1. Summary + +The multi-search endpoint performs a batch of search queries as if using the [search API](./0118-search-api.md). + +## 2. Motivation + +- Perform multiple queries in a single HTTP request + +## 3. Functional Specification + +Meilisearch exposes 1 route to perform multi-search requests: + +- POST `/multi-search` + +If a master key is used to secure a Meilisearch instance, the auth layer returns the following errors: + +- 🔴 Accessing these routes without the `Authorization` header returns a [missing_authorization_header](0061-error-format-and-definitions.md#missing_authorization_header) error. +- 🔴 Accessing these routes with a key that does not have permissions (i.e. other than the master key) returns an [invalid_api_key](0061-error-format-and-definitions.md#invalid_api_key) error. + +If any of the search queries fail to execute, the response returns the corresponding error instead of the array of results. + +`POST` HTTP verb errors: + +- 🔴 Omitting the Content-Type header returns a [missing_content_type](0061-error-format-and-definitions.md#missing_content_type) error. +- 🔴 Sending an empty Content-Type returns an [invalid_content_type](0061-error-format-and-definitions.md#invalid_content_type) error. +- 🔴 Sending a different Content-Type than `application/json` returns an [invalid_content_type](0061-error-format-and-definitions.md#invalid_content_type) error. +- 🔴 Sending an empty payload returns a [missing_payload](0061-error-format-and-definitions.md#missing_payload) error. +- 🔴 Sending an invalid JSON payload returns a [malformed_payload](0061-error-format-and-definitions.md#malformed_payload) error. + +### 3.1. Search Payload Parameters + +| Field | Type | Required | +|--------------|------------------|----------| +| [`queries`](#311-queries) | Array of Objects | True | + +#### 3.1.1. `queries` + +- Type: Object +- Required: True + +The `queries` object contains the list of search queries to perform. + +Each element of this array is a JSON object with the required field `indexUid`, the uid of the index to be searched. Other fields of this object are optional, and identical to the ones in the [existing search routes](./0118-search-api.md#31-search-payload-parameters) (`q`, `limit`, etc.). + +### 3.2. Search Response Properties + +| Field | Type | Required | +|---------------------------|---------------|----------| +| [`results`](#321-results) | Array[Object] | True | + +#### 3.2.1. `results` + +- Type: Array[Objets] +- Required: True + +Results of the search queries as an array of search results. + +Each element of this array is a JSON object representing the results of the search query with the same index in the `queries` array from the request, and an additional `indexUid` field that is equal to the `indexUid` field in that search query. + +The other fields of an element from the `results` array are identical to the fields of the [response from the other search routes](./0118-search-api.md#31-formatting-search-results). + +## 2. Technical Details +n/a + +## 3. Future Possibilities + +- Allow specifying an index uid pattern instead of an index uid to produce searches on all indexes matching the pattern. +- Allow additional arguments to the request specifying a strategy to aggregate results from the multiple searches. From c6df9878a82a68b4cf6e30dd73bfe80704aeaeae Mon Sep 17 00:00:00 2001 From: Louis Dureuil Date: Mon, 27 Feb 2023 16:01:43 +0100 Subject: [PATCH 02/15] Change possible HTTP return codes for index_not_found --- text/0061-error-format-and-definitions.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/text/0061-error-format-and-definitions.md b/text/0061-error-format-and-definitions.md index 273f7930..d3be3451 100644 --- a/text/0061-error-format-and-definitions.md +++ b/text/0061-error-format-and-definitions.md @@ -1856,7 +1856,9 @@ This error happens when a requested index can't be found. ### Error Definition -HTTP Code: `404 Not Found` when `Synchronous` +HTTP Code when `Synchronous`: +- if the index uid was specified as part of the URL, `404 Not Found` +- if the index uid was specified as part of the POST body, `400 Bad Request` #### Variant: Multiples indexUids can't be found From 493c758508072644c3b634972c18733097859af9 Mon Sep 17 00:00:00 2001 From: Louis Dureuil Date: Mon, 27 Feb 2023 16:02:06 +0100 Subject: [PATCH 03/15] Add multi-search to openAPI --- open-api.yaml | 319 ++++++++++++++++++++++++++++++++++---------------- 1 file changed, 216 insertions(+), 103 deletions(-) diff --git a/open-api.yaml b/open-api.yaml index 27d6296d..cf36e959 100644 --- a/open-api.yaml +++ b/open-api.yaml @@ -644,6 +644,109 @@ components: - numberOfDocuments - isIndexing - fieldDistribution + searchQuery: + type: object + additionalProperties: false + properties: + q: + type: string + description: Query string. + default: '""' + example: '"Back to the future"' + attributesToRetrieve: + type: array + description: 'Array of attributes whose fields will be present in the returned documents. Defaults to the [displayedAttributes list](https://docs.meilisearch.com/reference/features/settings.html#displayed-attributes) which contains by default all attributes found in the documents.' + items: + type: string + example: '["title", "overview"]' + default: '["*"]' + attributesToHighlight: + type: array + description: Array of attributes whose values will contain highlighted matching terms. Highlighted attributes are returned in `_formatted` response object. + items: + type: string + example: '["title", "overview"]' + default: '[]' + highlightPreTag: + type: string + description: Specify the tag to put before the highlighted query terms. + example: '' + default: '' + highlightPostTag: + type: string + description: Specify the tag to put after the highlighted query terms. + example: '' + default: '' + attributesToCrop: + type: array + description: Array of attributes whose values have to be cropped. Cropped attributes are returned in `_formatted` response object. + items: + type: string + example: '["overview", "author"]' + default: '[]' + cropMarker: + type: string + description: Sets the crop marker to apply before and/or after cropped part selected within an attribute defined in `attributesToCrop` parameter. + default: '…' + cropLength: + type: number + description: Sets the total number of **words** to keep for the cropped part of an attribute specified in the `attributesToCrop` parameter. + default: 10 + showMatchesPosition: + type: boolean + description: Defines whether an `_matchesPosition` object that contains information about the matches should be returned or not. + default: false + matchingStrategy: + type: string + description: Defines which strategy to use to match the query terms within the documents as search results. Two different strategies are available, `last` and `all`. By default, the `last` strategy is chosen. + default: 'last' + filter: + $ref: '#/components/schemas/filter' + facets: + type: array + description: 'Array of attributes whose fields will be distributed as a facet. If you have [set up filterableAttributes](https://docs.meilisearch.com/reference/features/settings.html#filterable-attributes), you can retrieve the count of matching terms for each [facets](https://docs.meilisearch.com/reference/features/filtering_and_faceted_search.html#faceted-search).[Learn more about facet distribution in the dedicated guide](https://docs.meilisearch.com/reference/features/search_parameters.html#facet-distribution)' + items: + type: string + example: '["genres", "author"]' + default: '[]' + offset: + type: number + description: Number of documents to skip. + default: 0 + limit: + type: number + description: Maximum number of documents returned. + default: 20 + page: + type: number + description: The specific search results page to fetch. + example: 1 + hitsPerPage: + type: number + description: Number of returned results per page. + example: 20 + sort: + $ref: '#/components/schemas/sort' + examples: + Example: + value: + q: Harry + offset: 0 + limit: 20 + filter: (genres = Horror AND genres = Mystery) OR release_date > 523242000 + facets: + - genres + - author + attributesToRetrieve: + - title + - overview + attributesToCrop: + - overview + cropLength: 20 + attributesToHighlight: + - overview + showMatchesPosition: true + wordsMatchingStrategy: all error: title: error type: object @@ -1188,10 +1291,11 @@ tags: [Learn more about documents](https://docs.meilisearch.com/learn/core_concepts/documents.html). - name: Search description: | - Meilisearch exposes 2 routes to perform searches: + Meilisearch exposes 3 routes to perform searches: * A POST route: this is the preferred route when using API authentication, as it allows [preflight request](https://developer.mozilla.org/en-US/docs/Glossary/Preflight_request) caching and better performances. * A GET route: the usage of this route is discouraged, unless you have good reason to do otherwise (specific caching abilities for example). Other than the differences mentioned above, the two routes are strictly equivalent. + * A multi-search route allowing to perform multiple search queries in a single HTTP request. - name: Tasks description: | The `tasks` route gives information about the progress of the [asynchronous operations](https://docs.meilisearch.com/learn/advanced/asynchronous_operations.html). @@ -1849,108 +1953,7 @@ paths: content: application/json: schema: - type: object - additionalProperties: false - properties: - q: - type: string - description: Query string. - default: '""' - example: '"Back to the future"' - attributesToRetrieve: - type: array - description: 'Array of attributes whose fields will be present in the returned documents. Defaults to the [displayedAttributes list](https://docs.meilisearch.com/reference/features/settings.html#displayed-attributes) which contains by default all attributes found in the documents.' - items: - type: string - example: '["title", "overview"]' - default: '["*"]' - attributesToHighlight: - type: array - description: Array of attributes whose values will contain highlighted matching terms. Highlighted attributes are returned in `_formatted` response object. - items: - type: string - example: '["title", "overview"]' - default: '[]' - highlightPreTag: - type: string - description: Specify the tag to put before the highlighted query terms. - example: '' - default: '' - highlightPostTag: - type: string - description: Specify the tag to put after the highlighted query terms. - example: '' - default: '' - attributesToCrop: - type: array - description: Array of attributes whose values have to be cropped. Cropped attributes are returned in `_formatted` response object. - items: - type: string - example: '["overview", "author"]' - default: '[]' - cropMarker: - type: string - description: Sets the crop marker to apply before and/or after cropped part selected within an attribute defined in `attributesToCrop` parameter. - default: '…' - cropLength: - type: number - description: Sets the total number of **words** to keep for the cropped part of an attribute specified in the `attributesToCrop` parameter. - default: 10 - showMatchesPosition: - type: boolean - description: Defines whether an `_matchesPosition` object that contains information about the matches should be returned or not. - default: false - matchingStrategy: - type: string - description: Defines which strategy to use to match the query terms within the documents as search results. Two different strategies are available, `last` and `all`. By default, the `last` strategy is chosen. - default: 'last' - filter: - $ref: '#/components/schemas/filter' - facets: - type: array - description: 'Array of attributes whose fields will be distributed as a facet. If you have [set up filterableAttributes](https://docs.meilisearch.com/reference/features/settings.html#filterable-attributes), you can retrieve the count of matching terms for each [facets](https://docs.meilisearch.com/reference/features/filtering_and_faceted_search.html#faceted-search).[Learn more about facet distribution in the dedicated guide](https://docs.meilisearch.com/reference/features/search_parameters.html#facet-distribution)' - items: - type: string - example: '["genres", "author"]' - default: '[]' - offset: - type: number - description: Number of documents to skip. - default: 0 - limit: - type: number - description: Maximum number of documents returned. - default: 20 - page: - type: number - description: The specific search results page to fetch. - example: 1 - hitsPerPage: - type: number - description: Number of returned results per page. - example: 20 - sort: - $ref: '#/components/schemas/sort' - examples: - Example: - value: - q: Harry - offset: 0 - limit: 20 - filter: (genres = Horror AND genres = Mystery) OR release_date > 523242000 - facets: - - genres - - author - attributesToRetrieve: - - title - - overview - attributesToCrop: - - overview - cropLength: 20 - attributesToHighlight: - - overview - showMatchesPosition: true - wordsMatchingStrategy: all + $ref: '#/components/schemas/searchQuery' responses: '200': description: Ok @@ -3180,6 +3183,116 @@ paths: description: Not Found parameters: - $ref: '#/components/parameters/indexUid' + /multi-search: + post: + operationId: multi_search + summary: Make multiple search queries in a single request + description: | + Make multiple search queries in a single request. + + The queries can span different indexes or lookup the results of different filters on the same index. + tags: + - Search + security: + - apiKey: [] + requestBody: + required: true + content: + application/json: + schema: + type: object + additionalProperties: false + properties: + queries: + type: array + description: Array of the search queries to be performed. + items: + type: object + additionalProperties: false + properties: + indexUid: + type: string + description: The unique identifier of the index to be searched. + $ref: '#/components/schemas/searchQuery/properties' + examples: + Example: + value: + indexUid: movies + $ref: '#components/schemas/searchQuery/examples/Example/value' + required: + - indexUid + required: + - queries + examples: + Example: + - value: + indexUid: movies + q: Harry + offset: 0 + limit: 20 + filter: (genres = Horror AND genres = Mystery) OR release_date > 523242000 + facets: + - genres + - author + attributesToRetrieve: + - title + - overview + attributesToCrop: + - overview + cropLength: 20 + attributesToHighlight: + - overview + showMatchesPosition: true + wordsMatchingStrategy: all + responses: + '200': + description: Ok + content: + application/json: + schema: + type: object + additionalProperties: false + properties: + results: + type: array + items: + type: object + properties: + indexUid: + type: string + description: The unique identifier of the searched index. + $ref: '#/components/schemas/searchResponse/properties' + examples: + Example: + - value: + indexUid: movies + hits: + - id: 25684 + title: American Ninja 5 + poster: 'https://image.tmdb.org/t/p/w1280/iuAQVI4mvjI83wnirpD8GVNRVuY.jpg' + overview: 'When a scientists daughter is kidnapped, American Ninja, attempts to find her, but this time he teams up with a youngster he has trained in the ways of the ninja.' + release_date: 725846400 + _formatted: + id: 25684 + title: American Ninja 5 + poster: 'https://image.tmdb.org/t/p/w1280/iuAQVI4mvjI83wnirpD8GVNRVuY.jpg' + overview: 'When a scientists daughter is kidnapped, American Ninja, attempts to find her, but this time he teams up with a youngster he has trained in the ways of the ninja.' + release_date: 725846400 + _matchesPosition: + overview: + - start: 49 + length: 5 + - start: 155 + length: 5 + limit: 0 + offset: 0 + estimatedTotalHits: 0 + query: string + processingTimeMs: 0 + '401': + $ref: '#/components/responses/401' + parameters: + - $ref: '#/components/parameters/Content-Type' /keys: get: operationId: keys.list From b5df7905d5b41e575c87320d9d13af010b686ff9 Mon Sep 17 00:00:00 2001 From: Louis Dureuil Date: Mon, 27 Feb 2023 16:25:21 +0100 Subject: [PATCH 04/15] Update telemetry --- text/0034-telemetry-policies.md | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/text/0034-telemetry-policies.md b/text/0034-telemetry-policies.md index b48a8c6e..0b503f8e 100644 --- a/text/0034-telemetry-policies.md +++ b/text/0034-telemetry-policies.md @@ -40,6 +40,7 @@ The collected data is sent to [Segment](https://segment.com/). Segment is a plat | Launched | Occurs when MeiliSearch is launched the first time. | | Documents Searched POST | Aggregated event on all received requests via the `POST` - `indexes/:indexUid/search` route during one hour or until a batch size reaches `500Kb`. | | Documents Searched GET | Aggregated event on all received requests via the `GET` - `/indexes/:indexUid/search` route during one hour or until a batch size reaches `500Kb`. | +| Documents Searched by Multi-Search POST | Aggregated event on all received requests via the `POST`- `/multi-search` route during one hour or until a batch size reaches `500Kb`. | | Documents Added | Aggregated event on all received requests via the `POST` - `/indexes/:indexUid/documents` route during one hour or until a batch size reaches `500Kb`. | | Documents Updated | Aggregated event on all received requests via the `PUT` - `/indexes/:indexUid/documents` route during one hour or until a batch size reaches `500Kb`. | | Documents Deleted | Aggregated event on all received requests via the `DELETE` - `/indexes/:indexUid/documents`, `DELETE` - `/indexes/:indexUid/documents/:documentId`, `POST` - `indexes/:indexUid/documents/delete-batch` routes during one hour or until a batch size reaches `500Kb`. | @@ -106,11 +107,11 @@ The collected data is sent to [Segment](https://segment.com/). Segment is a plat | `stats.database_size` | Database size. Expressed in `Bytes` | 2621440 | Every hour | | `stats.indexes_number` | Number of indexes | 2 | Every hour | | `start_since_days` | Number of days since instance was launched | 365 | Every hour | -| `user_agent` | User-agent header encountered during one or more API calls | ["Meilisearch Ruby (v2.1)", "Ruby (3.0)"] | `Documents Searched POST`, `Documents Searched GET`, `Index Created`, `Index Updated`, `Documents Added`, `Documents Updated`, `Documents Deleted`, `Settings Updated`, `Ranking Rules Updated`, `SortableAttributes Updated`, `FilterableAttributes Updated`, `SearchableAttributes Updated`, `TypoTolerance Updated`, `Pagination Updated`, `Faceting Updated`, `DistinctAttribute Updated`, `DisplayedAttributes Updated`, `StopWords Updated`, `Synonyms Updated`, `Dump Created`, `Tasks Seen`, `Stats Seen`, `Health Seen`, `Version Seen` | +| `user_agent` | User-agent header encountered during one or more API calls | ["Meilisearch Ruby (v2.1)", "Ruby (3.0)"] | `Documents Searched POST`, `Documents Searched GET`, `Index Created`, `Index Updated`, `Documents Added`, `Documents Updated`, `Documents Deleted`, `Settings Updated`, `Ranking Rules Updated`, `SortableAttributes Updated`, `FilterableAttributes Updated`, `SearchableAttributes Updated`, `TypoTolerance Updated`, `Pagination Updated`, `Faceting Updated`, `DistinctAttribute Updated`, `DisplayedAttributes Updated`, `StopWords Updated`, `Synonyms Updated`, `Dump Created`, `Tasks Seen`, `Stats Seen`, `Health Seen`, `Version Seen`, `Documents Searched by Multi-Search POST` | | `requests.99th_response_time` | Highest latency from among the fastest 99% of successful search requests | 57ms | `Documents Searched POST`, `Documents Searched GET`| -| `requests.total_succeeded` | Total number of successful requests in this batch | 3456 | `Documents Searched POST`, `Documents Searched GET` | -| `requests.total_failed` | Total number of failed requests in this batch | 24 | `Documents Searched POST`, `Documents Searched GET` | -| `requests.total_received` | Total number of received requests in this batch | 3480 | `Documents Searched POST`, `Documents Searched GET`, `Documents Deleted`, `Health Seen`, `Tasks Seen` | +| `requests.total_succeeded` | Total number of successful requests in this batch | 3456 | `Documents Searched POST`, `Documents Searched GET`, `Documents Searched by Multi-Search POST` | +| `requests.total_failed` | Total number of failed requests in this batch | 24 | `Documents Searched POST`, `Documents Searched GET`, `Documents Searched by Multi-Search POST` | +| `requests.total_received` | Total number of received requests in this batch | 3480 | `Documents Searched POST`, `Documents Searched GET`, `Documents Deleted`, `Health Seen`, `Tasks Seen`, `Documents Searched by Multi-Search POST` | | `sort.with_geoPoint` | `true` if the sort rule `_geoPoint` was used in this batch, otherwise `false` | true | `Documents Searched POST`, `Documents Searched GET` | | `sort.avg_criteria_number` | Average number of sort criteria among all requests containing the `sort` parameter in this batch | 2 | `Documents Searched POST`, `Documents Searched GET` | | `filter.with_geoRadius` | `true` if the filter rule `_geoRadius` was used in this batch, otherwise `false` | false | `Documents Searched POST`, `Documents Searched GET` | @@ -169,6 +170,11 @@ The collected data is sent to [Segment](https://segment.com/). Segment is a plat | `filtered_by_before_finished_at` | `true` if tasks are filtered by the `beforeFinishedAt` query parameter, otherwise `false` | false | `Tasks Seen`, `Tasks Canceled`, `Tasks Deleted` | | `filtered_by_after_finished_at` | `true` if tasks are filtered by the `afterFinishedAt` query parameter, otherwise `false` | false | `Tasks Seen`, `Tasks Canceled`, `Tasks Deleted` | | `per_index_uid` | `true` if an uid is used to fetch an index stat resource, otherwise `false` | false | `Stats Seen` | +| searches.avg_search_count | The average number of search queries received per call for the aggregated event. | `4.2` | `Documents Searched by Multi-Search POST` | +| searches.total_search_count | The total number of search queries received for the aggregated event. | `16023` | `Documents Searched by Multi-Search POST` | +| indexes.avg_distinct_index_count | The average number of queried indexes received per call for the aggregated event. | `1.2` | `Documents Searched by Multi-Search POST` +| indexes.total_distinct_index_count | The total number of distinct indexes queries for the aggregated event. | `6023` | `Documents Searched by Multi-Search POST` +| indexes.total_single_index | The total number of calls where only one index where queried. | `2007` | `Documents Searched by Multi-Search POST` | `swap_operation_number` | The number of swap operation given in `POST /swap-indexes` API call | 2 | `Indexes Swapped` | | `matching_strategy.most_used_strategy` | Most used word matching strategy among all search requests in this batch | `last` | `Documents Searched POST`, `Documents Searched GET` | | `per_document_id` | `true` if `DELETE /indexes/:indexUid/documents/:documentUid` endpoint was used in this batch, otherwise `false` | false | `Documents Deleted` | @@ -303,6 +309,23 @@ This property allows us to gather essential information to better understand on --- +#### `Documents Searched by Multi-Search POST` + +> The Documents Searched event is sent once an hour or when a batch reaches the maximum size of `500kb`. The event's properties are averaged over all requests on `POST` - `/multi-search`. + +| Property name | Description | Example | +|---------------|-------------|---------| +| user_agent | Represents all the user-agents encountered on this endpoint in the aggregated event.| `["Meilisearch Ruby (v2.1)", "Ruby (3.0)"]` | +| requests.total_succeeded | The number of succeeded calls on the endpoint for the aggregated event. | `3456` | +| requests.total_failed | The number of calls on the endpoint for the aggregated event. | `24` | +| requests.total_received | The number of calls on the endpoint for the aggregated event. | `3480` | +| searches.avg_search_count | The average number of search queries received per call for the aggregated event. | `4.2` | +| searches.total_search_count | The total number of search queries received for the aggregated event. | `16023` | +| indexes.avg_distinct_index_count | The average number of queried indexes received per call for the aggregated event. | `1.2` +| indexes.total_distinct_index_count | The total number of distinct indexes queries for the aggregated event. | `6023` +| indexes.total_single_index | The total number of calls where only one index where queried. | `2007` + + ## `Index Created` | Property name | Description | Example | From 3bb149844e17eea816f19e57d9cb09976b5454d6 Mon Sep 17 00:00:00 2001 From: Louis Dureuil Date: Mon, 27 Feb 2023 16:36:02 +0100 Subject: [PATCH 05/15] openAPI: shorter summary for multi-search --- open-api.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/open-api.yaml b/open-api.yaml index cf36e959..df660a35 100644 --- a/open-api.yaml +++ b/open-api.yaml @@ -3186,7 +3186,7 @@ paths: /multi-search: post: operationId: multi_search - summary: Make multiple search queries in a single request + summary: Multiple Search description: | Make multiple search queries in a single request. From d496fe51063e2e1d5a0a5ac1da6a06ed8fb798b3 Mon Sep 17 00:00:00 2001 From: Louis Dureuil Date: Mon, 27 Feb 2023 16:36:16 +0100 Subject: [PATCH 06/15] openAPI: attempt to remove superfluous "values" field in multisearch request/response --- open-api.yaml | 80 +++++++++++++++++++++++++-------------------------- 1 file changed, 39 insertions(+), 41 deletions(-) diff --git a/open-api.yaml b/open-api.yaml index df660a35..89cf3579 100644 --- a/open-api.yaml +++ b/open-api.yaml @@ -3225,25 +3225,24 @@ paths: - queries examples: Example: - - value: - indexUid: movies - q: Harry - offset: 0 - limit: 20 - filter: (genres = Horror AND genres = Mystery) OR release_date > 523242000 - facets: - - genres - - author - attributesToRetrieve: - - title - - overview - attributesToCrop: - - overview - cropLength: 20 - attributesToHighlight: - - overview - showMatchesPosition: true - wordsMatchingStrategy: all + - indexUid: movies + q: Harry + offset: 0 + limit: 20 + filter: (genres = Horror AND genres = Mystery) OR release_date > 523242000 + facets: + - genres + - author + attributesToRetrieve: + - title + - overview + attributesToCrop: + - overview + cropLength: 20 + attributesToHighlight: + - overview + showMatchesPosition: true + wordsMatchingStrategy: all responses: '200': description: Ok @@ -3264,31 +3263,30 @@ paths: $ref: '#/components/schemas/searchResponse/properties' examples: Example: - - value: - indexUid: movies - hits: - - id: 25684 + - indexUid: movies + hits: + - id: 25684 + title: American Ninja 5 + poster: 'https://image.tmdb.org/t/p/w1280/iuAQVI4mvjI83wnirpD8GVNRVuY.jpg' + overview: 'When a scientists daughter is kidnapped, American Ninja, attempts to find her, but this time he teams up with a youngster he has trained in the ways of the ninja.' + release_date: 725846400 + _formatted: + id: 25684 title: American Ninja 5 poster: 'https://image.tmdb.org/t/p/w1280/iuAQVI4mvjI83wnirpD8GVNRVuY.jpg' - overview: 'When a scientists daughter is kidnapped, American Ninja, attempts to find her, but this time he teams up with a youngster he has trained in the ways of the ninja.' + overview: 'When a scientists daughter is kidnapped, American Ninja, attempts to find her, but this time he teams up with a youngster he has trained in the ways of the ninja.' release_date: 725846400 - _formatted: - id: 25684 - title: American Ninja 5 - poster: 'https://image.tmdb.org/t/p/w1280/iuAQVI4mvjI83wnirpD8GVNRVuY.jpg' - overview: 'When a scientists daughter is kidnapped, American Ninja, attempts to find her, but this time he teams up with a youngster he has trained in the ways of the ninja.' - release_date: 725846400 - _matchesPosition: - overview: - - start: 49 - length: 5 - - start: 155 - length: 5 - limit: 0 - offset: 0 - estimatedTotalHits: 0 - query: string - processingTimeMs: 0 + _matchesPosition: + overview: + - start: 49 + length: 5 + - start: 155 + length: 5 + limit: 0 + offset: 0 + estimatedTotalHits: 0 + query: string + processingTimeMs: 0 '401': $ref: '#/components/responses/401' parameters: From 8ef6dd7a08038315907231cce9dddaa444fe76ae Mon Sep 17 00:00:00 2001 From: Louis Dureuil Date: Tue, 28 Feb 2023 10:58:24 +0100 Subject: [PATCH 07/15] Apply review suggestions for openAPI Co-authored-by: Guillaume Mourier --- open-api.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/open-api.yaml b/open-api.yaml index 89cf3579..9e04309f 100644 --- a/open-api.yaml +++ b/open-api.yaml @@ -1295,7 +1295,7 @@ tags: * A POST route: this is the preferred route when using API authentication, as it allows [preflight request](https://developer.mozilla.org/en-US/docs/Glossary/Preflight_request) caching and better performances. * A GET route: the usage of this route is discouraged, unless you have good reason to do otherwise (specific caching abilities for example). Other than the differences mentioned above, the two routes are strictly equivalent. - * A multi-search route allowing to perform multiple search queries in a single HTTP request. + * A POST multi-search route allowing to perform multiple search queries in a single HTTP request. - name: Tasks description: | The `tasks` route gives information about the progress of the [asynchronous operations](https://docs.meilisearch.com/learn/advanced/asynchronous_operations.html). @@ -3188,9 +3188,9 @@ paths: operationId: multi_search summary: Multiple Search description: | - Make multiple search queries in a single request. + Make multiple search queries in a single HTTP request. - The queries can span different indexes or lookup the results of different filters on the same index. + The queries can span different indexes or lookup the results of different filters on the same index. Each query has its own results set. tags: - Search security: From 6cd7c59dab3392bb6e4e3d0944bf05f9d7141e6c Mon Sep 17 00:00:00 2001 From: Louis Dureuil Date: Tue, 28 Feb 2023 10:59:30 +0100 Subject: [PATCH 08/15] Apply review suggestions for multi search API Co-authored-by: Guillaume Mourier --- text/0192-multi-search-api.md | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/text/0192-multi-search-api.md b/text/0192-multi-search-api.md index f37bad48..600aeadf 100644 --- a/text/0192-multi-search-api.md +++ b/text/0192-multi-search-api.md @@ -2,7 +2,14 @@ ## 1. Summary -The multi-search endpoint performs a batch of search queries as if using the [search API](./0118-search-api.md). +The multi-search endpoint performs a batch of search queries as if using the [search API](./0118-search-api.md) for an index. + +This endpoint allows, for example: + +- Execute different search queries on the same index +- Execute the same search query on different indexes + +Each search query has its own results set. ## 2. Motivation @@ -28,6 +35,8 @@ If any of the search queries fail to execute, the response returns the correspon - 🔴 Sending a different Content-Type than `application/json` returns an [invalid_content_type](0061-error-format-and-definitions.md#invalid_content_type) error. - 🔴 Sending an empty payload returns a [missing_payload](0061-error-format-and-definitions.md#missing_payload) error. - 🔴 Sending an invalid JSON payload returns a [malformed_payload](0061-error-format-and-definitions.md#malformed_payload) error. +- 🔴 Sending an inexistent `indexUid` in a query object returns an [index_not_found](0061-error-format-and-definitions.md#index_not_found) error. +- 🔴 Sending an invalid format for the `indexUid` property in a query object returns an [invalid_index_uid](0061-error-format-and-definitions.md#invalid_index_uid) error. ### 3.1. Search Payload Parameters From 40d3b6fa94f1666072e3f6a38c9c250578fc3806 Mon Sep 17 00:00:00 2001 From: Louis Dureuil Date: Tue, 28 Feb 2023 16:11:09 +0100 Subject: [PATCH 09/15] Add queries/results keys to openAPI examples Co-authored-by: Guillaume Mourier --- open-api.yaml | 40 +++++++++++++++++++++------------------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/open-api.yaml b/open-api.yaml index 9e04309f..7af997cc 100644 --- a/open-api.yaml +++ b/open-api.yaml @@ -3225,24 +3225,25 @@ paths: - queries examples: Example: - - indexUid: movies - q: Harry - offset: 0 - limit: 20 - filter: (genres = Horror AND genres = Mystery) OR release_date > 523242000 - facets: - - genres - - author - attributesToRetrieve: - - title - - overview - attributesToCrop: - - overview - cropLength: 20 - attributesToHighlight: - - overview - showMatchesPosition: true - wordsMatchingStrategy: all + queries: + - indexUid: movies + q: Harry + offset: 0 + limit: 20 + filter: (genres = Horror AND genres = Mystery) OR release_date > 523242000 + facets: + - genres + - author + attributesToRetrieve: + - title + - overview + attributesToCrop: + - overview + cropLength: 20 + attributesToHighlight: + - overview + showMatchesPosition: true + wordsMatchingStrategy: all responses: '200': description: Ok @@ -3263,7 +3264,8 @@ paths: $ref: '#/components/schemas/searchResponse/properties' examples: Example: - - indexUid: movies + results: + - indexUid: movies hits: - id: 25684 title: American Ninja 5 From 03feed446bc14b7d5edae8c8e9f78caaa05216dc Mon Sep 17 00:00:00 2001 From: Guillaume Mourier Date: Tue, 28 Feb 2023 17:21:47 +0100 Subject: [PATCH 10/15] fix indent --- open-api.yaml | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/open-api.yaml b/open-api.yaml index 7af997cc..84ff644d 100644 --- a/open-api.yaml +++ b/open-api.yaml @@ -3266,29 +3266,29 @@ paths: Example: results: - indexUid: movies - hits: - - id: 25684 - title: American Ninja 5 - poster: 'https://image.tmdb.org/t/p/w1280/iuAQVI4mvjI83wnirpD8GVNRVuY.jpg' - overview: 'When a scientists daughter is kidnapped, American Ninja, attempts to find her, but this time he teams up with a youngster he has trained in the ways of the ninja.' - release_date: 725846400 - _formatted: - id: 25684 + hits: + - id: 25684 title: American Ninja 5 poster: 'https://image.tmdb.org/t/p/w1280/iuAQVI4mvjI83wnirpD8GVNRVuY.jpg' - overview: 'When a scientists daughter is kidnapped, American Ninja, attempts to find her, but this time he teams up with a youngster he has trained in the ways of the ninja.' + overview: 'When a scientists daughter is kidnapped, American Ninja, attempts to find her, but this time he teams up with a youngster he has trained in the ways of the ninja.' release_date: 725846400 - _matchesPosition: - overview: - - start: 49 - length: 5 - - start: 155 - length: 5 - limit: 0 - offset: 0 - estimatedTotalHits: 0 - query: string - processingTimeMs: 0 + _formatted: + id: 25684 + title: American Ninja 5 + poster: 'https://image.tmdb.org/t/p/w1280/iuAQVI4mvjI83wnirpD8GVNRVuY.jpg' + overview: 'When a scientists daughter is kidnapped, American Ninja, attempts to find her, but this time he teams up with a youngster he has trained in the ways of the ninja.' + release_date: 725846400 + _matchesPosition: + overview: + - start: 49 + length: 5 + - start: 155 + length: 5 + limit: 0 + offset: 0 + estimatedTotalHits: 0 + query: string + processingTimeMs: 0 '401': $ref: '#/components/responses/401' parameters: From 858fea863d3d201daccbbd0270a83a6ee6cd7a31 Mon Sep 17 00:00:00 2001 From: Louis Dureuil Date: Wed, 1 Mar 2023 14:24:59 +0100 Subject: [PATCH 11/15] Apply review suggestions for multi search API Co-authored-by: cvermand <33010418+bidoubiwa@users.noreply.github.com> --- text/0192-multi-search-api.md | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/text/0192-multi-search-api.md b/text/0192-multi-search-api.md index 600aeadf..2958fac7 100644 --- a/text/0192-multi-search-api.md +++ b/text/0192-multi-search-api.md @@ -7,7 +7,7 @@ The multi-search endpoint performs a batch of search queries as if using the [se This endpoint allows, for example: - Execute different search queries on the same index -- Execute the same search query on different indexes +- Execute search queries on different indexes Each search query has its own results set. @@ -26,7 +26,7 @@ If a master key is used to secure a Meilisearch instance, the auth layer returns - 🔴 Accessing these routes without the `Authorization` header returns a [missing_authorization_header](0061-error-format-and-definitions.md#missing_authorization_header) error. - 🔴 Accessing these routes with a key that does not have permissions (i.e. other than the master key) returns an [invalid_api_key](0061-error-format-and-definitions.md#invalid_api_key) error. -If any of the search queries fail to execute, the response returns the corresponding error instead of the array of results. +If any of the search queries fail to execute, the response returns the corresponding error instead of the array of results. If multiple queries would have failed, only the first encountered failure is returned. `POST` HTTP verb errors: @@ -66,7 +66,34 @@ Each element of this array is a JSON object with the required field `indexUid`, Results of the search queries as an array of search results. -Each element of this array is a JSON object representing the results of the search query with the same index in the `queries` array from the request, and an additional `indexUid` field that is equal to the `indexUid` field in that search query. +Each element in this array contains the results of the search queries in the same order they have been requested. Additionally to the [usual fields returned by a search result](./0118-search-api.md#31-formatting-search-results), an `indexUid` field is present with the index UID on which the search has been performed. + +example: + +Search queries: +```json +{ + "queries": [ { "indexUid": "movie", "q": "wonder" }, { "indexUid": "books", "q": "king" } ] +} +''' + +Search results: +```json +{ + "results": [ + { + "indexUid": "movie", + "hits": [ { "title": "wonderwoman" } ], + // other search results fields: processingTimeMs, limit, ... + }, + { + "indexUid": "books", + "hits": [ { "title": "king kong theory" } ], + // other search results fields: processingTimeMs, limit, ... + }, + ] +} +``` The other fields of an element from the `results` array are identical to the fields of the [response from the other search routes](./0118-search-api.md#31-formatting-search-results). From ee5a2bca71b9f3c85da981c313124a3ea372de1b Mon Sep 17 00:00:00 2001 From: Louis Dureuil Date: Wed, 1 Mar 2023 14:25:50 +0100 Subject: [PATCH 12/15] OpenAPI: Change summary to `Multi Search` --- open-api.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/open-api.yaml b/open-api.yaml index 84ff644d..46a74814 100644 --- a/open-api.yaml +++ b/open-api.yaml @@ -3186,7 +3186,7 @@ paths: /multi-search: post: operationId: multi_search - summary: Multiple Search + summary: Multi Search description: | Make multiple search queries in a single HTTP request. From 9d12bdcfc420fd1fff9bcb8dd29edbd1a9f76ff2 Mon Sep 17 00:00:00 2001 From: Louis Dureuil Date: Wed, 1 Mar 2023 15:49:25 +0100 Subject: [PATCH 13/15] use backticks instead of ticks in multi search API example --- text/0192-multi-search-api.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/text/0192-multi-search-api.md b/text/0192-multi-search-api.md index 2958fac7..13827dcc 100644 --- a/text/0192-multi-search-api.md +++ b/text/0192-multi-search-api.md @@ -75,7 +75,7 @@ Search queries: { "queries": [ { "indexUid": "movie", "q": "wonder" }, { "indexUid": "books", "q": "king" } ] } -''' +``` Search results: ```json From b92b36ac6df5c400f50b59eba21882d342b73ba1 Mon Sep 17 00:00:00 2001 From: Louis Dureuil Date: Thu, 2 Mar 2023 16:16:17 +0100 Subject: [PATCH 14/15] Apply review suggestions for multi search API Co-authored-by: Maryam <90181761+maryamsulemani97@users.noreply.github.com> --- text/0192-multi-search-api.md | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/text/0192-multi-search-api.md b/text/0192-multi-search-api.md index 13827dcc..02def32e 100644 --- a/text/0192-multi-search-api.md +++ b/text/0192-multi-search-api.md @@ -2,13 +2,7 @@ ## 1. Summary -The multi-search endpoint performs a batch of search queries as if using the [search API](./0118-search-api.md) for an index. - -This endpoint allows, for example: - -- Execute different search queries on the same index -- Execute search queries on different indexes - +The multi-search endpoint performs multiple search queries on one or more indexes by bundling them into a single request. Each search query has its own results set. ## 2. Motivation @@ -26,7 +20,7 @@ If a master key is used to secure a Meilisearch instance, the auth layer returns - 🔴 Accessing these routes without the `Authorization` header returns a [missing_authorization_header](0061-error-format-and-definitions.md#missing_authorization_header) error. - 🔴 Accessing these routes with a key that does not have permissions (i.e. other than the master key) returns an [invalid_api_key](0061-error-format-and-definitions.md#invalid_api_key) error. -If any of the search queries fail to execute, the response returns the corresponding error instead of the array of results. If multiple queries would have failed, only the first encountered failure is returned. +If any of the search queries fail to execute, the response returns the corresponding error instead of the array of results. If multiple queries fail, only the first encountered failure is returned. `POST` HTTP verb errors: From f261a25639a105e9f409c7ded2c6fdcd369aaa89 Mon Sep 17 00:00:00 2001 From: Louis Dureuil Date: Thu, 2 Mar 2023 17:01:09 +0100 Subject: [PATCH 15/15] remove superfluous newline from telemetry file Co-authored-by: Guillaume Mourier --- text/0034-telemetry-policies.md | 1 - 1 file changed, 1 deletion(-) diff --git a/text/0034-telemetry-policies.md b/text/0034-telemetry-policies.md index 0b503f8e..7b1e237f 100644 --- a/text/0034-telemetry-policies.md +++ b/text/0034-telemetry-policies.md @@ -325,7 +325,6 @@ This property allows us to gather essential information to better understand on | indexes.total_distinct_index_count | The total number of distinct indexes queries for the aggregated event. | `6023` | indexes.total_single_index | The total number of calls where only one index where queried. | `2007` - ## `Index Created` | Property name | Description | Example |