From 4ad4d42e84ec71a0501c6c1ff8e344348603bedd Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Fri, 10 Apr 2026 11:49:29 +0200 Subject: [PATCH 1/4] Add search query endpoint with request examples Added a new search endpoint for querying resources with detailed request and response structures, including examples for various search scenarios. Based on the MS Graph Search Api of course: https://learn.microsoft.com/en-us/graph/api/resources/search-api-overview?view=graph-rest-1.0 --- api/openapi-spec/v1.0.yaml | 453 +++++++++++++++++++++++++++++++++++++ 1 file changed, 453 insertions(+) diff --git a/api/openapi-spec/v1.0.yaml b/api/openapi-spec/v1.0.yaml index da69c85..80ac564 100644 --- a/api/openapi-spec/v1.0.yaml +++ b/api/openapi-spec/v1.0.yaml @@ -4218,6 +4218,158 @@ paths: '@libre.graph.weight': 4 default: $ref: '#/components/responses/error' + /v1beta1/search/query: + post: + tags: + - search + summary: Search for resources + operationId: SearchQuery + description: | + Run a specified search query. Search results are provided in the response. + + The search endpoint allows clients to search for resources across all + accessible spaces and retrieve aggregated metadata (facets) about the + result set. + + Aggregations can be used to group results by properties such as file type, + author, or any indexed metadata field. This is useful for building faceted + search UIs or computing statistics about the result set. + + The query string uses KQL (Keyword Query Language) syntax for filtering. + + This endpoint is inspired by the + [MS Graph Search API](https://learn.microsoft.com/en-us/graph/api/search-query) + and follows the same request/response structure for compatibility. + requestBody: + required: true + content: + application/json: + schema: + type: object + required: + - requests + properties: + requests: + type: array + description: A collection of one or more search requests. + items: + $ref: '#/components/schemas/searchRequest' + examples: + simple search: + summary: Simple keyword search + value: + requests: + - entityTypes: + - driveItem + query: + queryString: budget report + from: 0 + size: 25 + search with aggregations: + summary: Search with term aggregation + value: + requests: + - entityTypes: + - driveItem + query: + queryString: "mediatype:audio" + from: 0 + size: 0 + aggregations: + - field: audio.artist + size: 10 + bucketDefinition: + sortBy: count + isDescending: true + minimumCount: 1 + search with range aggregation: + summary: Search with numeric range aggregation + value: + requests: + - entityTypes: + - driveItem + query: + queryString: "mediatype:audio" + size: 0 + aggregations: + - field: audio.year + bucketDefinition: + sortBy: keyAsString + isDescending: true + minimumCount: 0 + ranges: + - from: "1970" + to: "1980" + - from: "1980" + to: "1990" + - from: "1990" + to: "2000" + - from: "2000" + to: "2010" + - from: "2010" + search with aggregation filter: + summary: Narrow results using an aggregation filter from a previous search + value: + requests: + - entityTypes: + - driveItem + query: + queryString: "mediatype:audio" + from: 0 + size: 25 + aggregationFilters: + - "audio.artist:\"Pink Floyd\"" + responses: + '200': + description: OK + content: + application/json: + schema: + type: object + properties: + value: + type: array + description: A collection of search response objects, one per request. + items: + $ref: '#/components/schemas/searchResponse' + examples: + search results with aggregations: + value: + value: + - searchTerms: + - "mediatype:audio" + hitsContainers: + - hits: + - hitId: "4b478257-c9e8-458a-b764-fd7ed6cc1087$5d58a5c3-b244-4e9c-b082-82c3f1adbe8a!9d94e3d7" + rank: 1 + resource: + name: Comfortably Numb.flac + size: 45678901 + audio: + artist: Pink Floyd + album: The Wall + title: Comfortably Numb + genre: Rock + year: 1979 + track: 6 + disc: 2 + duration: 382000 + total: 142 + moreResultsAvailable: true + aggregations: + - field: audio.artist + buckets: + - key: Pink Floyd + count: 42 + aggregationFilterToken: Pink Floyd + - key: Led Zeppelin + count: 35 + aggregationFilterToken: Led Zeppelin + - key: The Beatles + count: 28 + aggregationFilterToken: The Beatles + default: + $ref: '#/components/responses/error' components: schemas: tagAssignment: @@ -5751,6 +5903,307 @@ components: # type: array # items: # type: string + searchRequest: + type: object + description: | + Represents an individual search request within a search query. Follows + the [MS Graph searchRequest](https://learn.microsoft.com/en-us/graph/api/resources/searchrequest) + resource type. + required: + - entityTypes + - query + properties: + entityTypes: + type: array + description: | + One or more types of resources expected in the response. Currently + only `driveItem` is supported. + items: + type: string + enum: + - driveItem + query: + $ref: '#/components/schemas/searchQuery' + from: + type: integer + format: int32 + description: | + Specifies the offset for the search results. Offset 0 returns the + very first result. Used together with the `size` property for + pagination. + default: 0 + minimum: 0 + size: + type: integer + format: int32 + description: | + The size of the page to be retrieved. The maximum value is 500. + Set to 0 to return only aggregations without any hits. + default: 25 + minimum: 0 + maximum: 500 + aggregations: + type: array + description: | + Specifies aggregations (also known as refiners or facets) to be + returned alongside the search results. Optional. + items: + $ref: '#/components/schemas/aggregationOption' + aggregationFilters: + type: array + description: | + Contains one or more filters to obtain search results narrowed down + to a specific value of a field. Build this filter based on a prior + search that aggregates by the same field. From the response of the + prior search, identify the `searchBucket` that filters results to + the specific value of the field, use the string in its + `aggregationFilterToken` property, and build an aggregation filter + string in the format `"{field}:\"{aggregationFilterToken}\""`. + + Multiple filters can be provided as separate array items. This + results in a logical AND between the filters. + items: + type: string + searchQuery: + type: object + description: | + Represents the search query. Follows the + [MS Graph searchQuery](https://learn.microsoft.com/en-us/graph/api/resources/searchquery) + resource type. + required: + - queryString + properties: + queryString: + type: string + description: | + The search query string in KQL (Keyword Query Language) format. The + query string can contain free-text keywords and property filters. + + Examples: + - `budget report` — free text search + - `mediatype:audio` — filter by media type + - `audio.artist:"Pink Floyd"` — filter by audio metadata + - `audio.genre:Rock AND audio.year:1979` — combined filters + aggregationOption: + type: object + description: | + Specifies an aggregation that should be computed and returned alongside + search results. Follows the + [MS Graph aggregationOption](https://learn.microsoft.com/en-us/graph/api/resources/aggregationoption) + resource type. + + For string fields, terms aggregations return the distinct values and + their counts. For numeric and date fields, range aggregations can be + defined using the `ranges` property of `bucketDefinition`. + required: + - field + - bucketDefinition + properties: + field: + type: string + description: | + Specifies the field in the schema of the specified entity type that + the aggregation should be computed on. Required. + + Examples: `audio.artist`, `audio.genre`, `audio.year`, `mimeType`. + size: + type: integer + format: int32 + description: | + The number of `searchBucket` resources to be returned. This is + optional and only applies to terms aggregations. Combined with + `bucketDefinition.sortBy` and `bucketDefinition.isDescending` to + produce the top N results by count or key. When not specified, all + buckets are returned. + minimum: 1 + bucketDefinition: + $ref: '#/components/schemas/bucketDefinition' + bucketDefinition: + type: object + description: | + Provides the details of how to generate the aggregation buckets in the + response. Follows the + [MS Graph bucketAggregationDefinition](https://learn.microsoft.com/en-us/graph/api/resources/bucketaggregationdefinition) + resource type. + required: + - sortBy + - isDescending + properties: + sortBy: + type: string + description: | + The possible values are `count` to sort by the number of matches in + the aggregation, `keyAsString` to sort alphabetically based on the + key in the aggregation, and `keyAsNumber` to sort numerically based + on the key in the aggregation. Required. + enum: + - count + - keyAsString + - keyAsNumber + isDescending: + type: boolean + description: | + Set to `true` to specify the sort order as descending. The default + is `false`, with the sort order as ascending. Required. + default: false + minimumCount: + type: integer + format: int32 + description: | + The minimum number of items that should be present in the + aggregation for the bucket to be returned in the response. + Optional, default is 0. + minimum: 0 + default: 0 + ranges: + type: array + description: | + Specifies the manual ranges to compute the aggregation buckets. + This is only valid for non-string facets of date or numeric type. + Optional. Follows the + [MS Graph bucketAggregationRange](https://learn.microsoft.com/en-us/graph/api/resources/bucketaggregationrange) + resource type. + items: + $ref: '#/components/schemas/bucketAggregationRange' + bucketAggregationRange: + type: object + description: | + Specifies the lower and upper bound to compute a range aggregation + bucket. At least one of `from` or `to` must be provided. + properties: + from: + type: string + description: | + Defines the lower bound from which to compute the aggregation. This + can be a numeric value or a string representation of a date using + the format `YYYY-MM-DDTHH:mm:ssZ`. Optional if `to` is provided. + to: + type: string + description: | + Defines the upper bound up to which to compute the aggregation. This + can be a numeric value or a string representation of a date using + the format `YYYY-MM-DDTHH:mm:ssZ`. Optional if `from` is provided. + searchResponse: + type: object + description: | + Represents the response for an individual search request. Follows the + [MS Graph searchResponse](https://learn.microsoft.com/en-us/graph/api/resources/searchresponse) + resource type. + properties: + searchTerms: + type: array + description: Contains the search terms sent in the initial search query. + items: + type: string + hitsContainers: + type: array + description: | + A collection of search result sets. One for each entity type that + was queried. + items: + $ref: '#/components/schemas/searchHitsContainer' + searchHitsContainer: + type: object + description: | + Contains a collection of search results. Follows the + [MS Graph searchHitsContainer](https://learn.microsoft.com/en-us/graph/api/resources/searchhitscontainer) + resource type. + properties: + hits: + type: array + description: A collection of the search results. + items: + $ref: '#/components/schemas/searchHit' + total: + type: integer + format: int64 + description: | + The total number of results. Note this is not the number of results + on the page, but the total number of results satisfying the query. + moreResultsAvailable: + type: boolean + description: | + Provides information if more results are available. Based on this + information, you can adjust the `from` and `size` properties of the + `searchRequest` accordingly. + aggregations: + type: array + description: | + Contains the collection of aggregations computed based on the + provided `aggregationOption` definitions in the request. + items: + $ref: '#/components/schemas/searchAggregation' + searchHit: + type: object + description: | + Represents an individual search result. Follows the + [MS Graph searchHit](https://learn.microsoft.com/en-us/graph/api/resources/searchhit) + resource type. + properties: + hitId: + type: string + description: The internal identifier for the item. + readOnly: true + rank: + type: integer + format: int32 + description: The rank or the order of the result. + readOnly: true + summary: + type: string + description: | + A summary of the result, if a summary is available. + readOnly: true + resource: + $ref: '#/components/schemas/driveItem' + searchAggregation: + type: object + description: | + Provides the details of a search aggregation in the search response. + Follows the + [MS Graph searchAggregation](https://learn.microsoft.com/en-us/graph/api/resources/searchaggregation) + resource type. + properties: + field: + type: string + description: | + Defines the field in the request on which the aggregation was + computed. + buckets: + type: array + description: | + Defines the computed buckets for this aggregation. Buckets are + sorted according to the `sortBy` and `isDescending` specified in + the `bucketDefinition` of the corresponding `aggregationOption`. + items: + $ref: '#/components/schemas/searchBucket' + searchBucket: + type: object + description: | + Represents a single bucket in a search aggregation result. Follows the + [MS Graph searchBucket](https://learn.microsoft.com/en-us/graph/api/resources/searchbucket) + resource type. + properties: + key: + type: string + description: | + The discrete value of the field that was used to compute the + aggregation. For terms aggregations this is the field value. For + range aggregations this is a string representation of the range. + count: + type: integer + format: int64 + description: | + The approximate number of search matches that share the same value + specified in the `key` property. + aggregationFilterToken: + type: string + description: | + A token containing the encoded filter to aggregate search matches + to the specific key value. To use the filter, pass the token as + part of the `aggregationFilters` property in a subsequent + `searchRequest`, in the format + `"{field}:\"{aggregationFilterToken}\""`. odata.error: required: - error From 75917bf0b34496fc7f08c821fbbafc0887cecefa Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Sat, 11 Apr 2026 09:58:46 +0200 Subject: [PATCH 2/4] fix: copilot review findings --- api/openapi-spec/v1.0.yaml | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/api/openapi-spec/v1.0.yaml b/api/openapi-spec/v1.0.yaml index 80ac564..a2b56d6 100644 --- a/api/openapi-spec/v1.0.yaml +++ b/api/openapi-spec/v1.0.yaml @@ -4252,6 +4252,7 @@ paths: requests: type: array description: A collection of one or more search requests. + minItems: 1 items: $ref: '#/components/schemas/searchRequest' examples: @@ -5918,6 +5919,7 @@ components: description: | One or more types of resources expected in the response. Currently only `driveItem` is supported. + minItems: 1 items: type: string enum: @@ -6027,7 +6029,6 @@ components: resource type. required: - sortBy - - isDescending properties: sortBy: type: string @@ -6043,8 +6044,8 @@ components: isDescending: type: boolean description: | - Set to `true` to specify the sort order as descending. The default - is `false`, with the sort order as ascending. Required. + Set to `true` to specify the sort order as descending. Optional, + defaults to `false` (ascending). default: false minimumCount: type: integer @@ -6070,6 +6071,11 @@ components: description: | Specifies the lower and upper bound to compute a range aggregation bucket. At least one of `from` or `to` must be provided. + anyOf: + - required: + - from + - required: + - to properties: from: type: string From bb7d333135ec1171c986197495eaf2cee1b1240b Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Sat, 11 Apr 2026 10:15:27 +0200 Subject: [PATCH 3/4] fix: copilot findings --- api/openapi-spec/v1.0.yaml | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/api/openapi-spec/v1.0.yaml b/api/openapi-spec/v1.0.yaml index a2b56d6..146247b 100644 --- a/api/openapi-spec/v1.0.yaml +++ b/api/openapi-spec/v1.0.yaml @@ -6080,15 +6080,17 @@ components: from: type: string description: | - Defines the lower bound from which to compute the aggregation. This - can be a numeric value or a string representation of a date using - the format `YYYY-MM-DDTHH:mm:ssZ`. Optional if `to` is provided. + Defines the lower bound from which to compute the aggregation. + The value is always a string. Numeric bounds must be provided as + their string representation (e.g. `"1980"`). Date bounds must use + the `YYYY-MM-DDTHH:mm:ssZ` format. Optional if `to` is provided. to: type: string description: | - Defines the upper bound up to which to compute the aggregation. This - can be a numeric value or a string representation of a date using - the format `YYYY-MM-DDTHH:mm:ssZ`. Optional if `from` is provided. + Defines the upper bound up to which to compute the aggregation. + The value is always a string. Numeric bounds must be provided as + their string representation (e.g. `"2000"`). Date bounds must use + the `YYYY-MM-DDTHH:mm:ssZ` format. Optional if `from` is provided. searchResponse: type: object description: | From 68fdbafecb622877631fc6b6f522d216d9d70f3d Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Sat, 11 Apr 2026 10:37:50 +0200 Subject: [PATCH 4/4] fix: some more improvements --- api/openapi-spec/v1.0.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/api/openapi-spec/v1.0.yaml b/api/openapi-spec/v1.0.yaml index 146247b..c09188b 100644 --- a/api/openapi-spec/v1.0.yaml +++ b/api/openapi-spec/v1.0.yaml @@ -5999,7 +5999,6 @@ components: defined using the `ranges` property of `bucketDefinition`. required: - field - - bucketDefinition properties: field: type: string @@ -6128,12 +6127,14 @@ components: description: | The total number of results. Note this is not the number of results on the page, but the total number of results satisfying the query. + readOnly: true moreResultsAvailable: type: boolean description: | Provides information if more results are available. Based on this information, you can adjust the `from` and `size` properties of the `searchRequest` accordingly. + readOnly: true aggregations: type: array description: |