Skip to content

feat(search): sort results via sortProperties / order_by - #3298

Draft
dschmidt wants to merge 14 commits into
feat/graph-search-queryfrom
feat/search-sort-properties
Draft

dschmidt wants to merge 14 commits into
feat/graph-search-queryfrom
feat/search-sort-properties

Conversation

@dschmidt

Copy link
Copy Markdown
Contributor

Adds MS-Graph-style sortProperties to the graph search endpoint and order_by to the search proto.

  • Sortable is any scalar field that is indexed and carried on the match entity, derived via reflection; multivalued and unknown fields are rejected with invalidRequest.
  • Native sorting in the bleve and OpenSearch backends, order-preserving cross-space merge (case-insensitive for lowercase-analyzed fields like name).
  • order_by is wired through the grpc service and its response cache key.

Spec: opencloud-eu/libre-graph-api#61
Stacked on #3211.

@codacy-production

codacy-production Bot commented Aug 12, 2026 •

Copy link
Copy Markdown

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

🟢 Metrics 133 complexity

Metric Results
Complexity 133

View in Codacy

NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.

@dschmidt
dschmidt force-pushed the feat/search-sort-properties branch from e443b80 to cc497cc Compare August 12, 2026 23:08
@dschmidt
dschmidt force-pushed the feat/search-sort-properties branch from cc497cc to 97626bb Compare August 18, 2026 17:11
@dschmidt
dschmidt force-pushed the feat/search-sort-properties branch from 97626bb to ac2f094 Compare September 7, 2026 22:35
Generated from opencloud-eu/libre-graph-api#34 rebased onto main: POST /search/query with hits, aggregations and metrics.
MS-Graph-style search query endpoint: hits from all accessible spaces, with from/size paging, remote items for hits from shared spaces, thumbnails on $expand, and the effective permission actions on every hit. The search proto gains the aggregation types of the graph API and the endpoint passes aggregations through to the search service, which does not evaluate them yet.
Term buckets on both engines: bleve facets, OpenSearch terms aggregations, buckets merged across spaces and post-processed per BucketDefinition (minimum count, sort, size). Terms aggregations on numeric fields are rejected at the graph endpoint. Pinned in the parity suite as AGG-01 to AGG-03. Ranges, metrics and sub-aggregations are declined until the engines evaluate them.
Numeric and date ranges on both engines: bleve numeric and date-time range facets, OpenSearch range and date_range aggregations, a bound that is neither number nor date is rejected. A terms aggregation on a numeric field now points to ranges as the alternative. AGG-04, 05 and 07 to 09 in the parity suite.
Sum, min, max and avg on both engines. bleve facets cannot compute, so a collector hooked into the document-match handler folds the metric from doc values, one pass over every match, before the top-n cut. Avg travels as sum and count so the service can reduce it across spaces. AGG-06 in the parity suite.
Sub-aggregations on both engines. bleve folds child buckets from doc values through the same collector as the metrics, terms and ranges alike; the service unions nested buckets across spaces. AGG-10 to AGG-16 in the parity suite.
Every bucket carries an opaque aggregationFilterToken; a search request can pass tokens back as aggregationFilters. The service decodes them into KQL fragments once, the engines AND them into the query as exact, case-sensitive matches.
Validated against the sortable-field whitelist (name, size,
lastModifiedDateTime, photo.takenDateTime) and forwarded to the search
service as order_by. Also fixes the stub search service's IndexSpace
signature (streaming response) so the suite builds again.

(cherry picked from commit 9aa6a34)
(cherry picked from commit 35a6cad8ea6a7890bdc0bc98c7ac97bdcbf477cc)
Name is analyzed (lowercaseKeyword) and therefore a text field, which
OpenSearch refuses to sort on without fielddata; enable it in the index
template. The keyword tokenizer emits one term per document, so the
fielddata cache stays small. The schema version has not shipped yet, so
no reindex is needed.

(cherry picked from commit f1d0e7b)
The grpc layer rebuilt the searcher request field by field and dropped
order_by; the response cache also ignored it, so differently sorted
searches collided on the same cache entry.

(cherry picked from commit 97626bb)
@dschmidt
dschmidt force-pushed the feat/search-sort-properties branch from 61cf668 to 3f2c988 Compare September 12, 2026 18:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant