Skip to content

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

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

feat(search): sort results via sortProperties / order_by#3298
dschmidt wants to merge 9 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

Not up to standards ⛔

🟢 Coverage 60.49% diff coverage

Metric Results
Coverage variation Report missing for 1b61ef61
Diff coverage 60.49% diff coverage

View coverage diff in Codacy

Coverage variation details
Coverable lines Covered lines Coverage
Common ancestor commit (1b61ef6) Report Missing Report Missing Report Missing
Head commit (cc497cc) 84682 20430 24.13%

Coverage variation is the difference between the coverage for the head and common ancestor commits of the pull request branch: <coverage of head commit> - <coverage of common ancestor commit>

Diff coverage details
Coverable lines Covered lines Diff coverage
Pull request (#3298) 324 196 60.49%

Diff coverage is the percentage of lines that are covered by tests out of the coverable lines that the pull request added or modified: <covered lines added or modified>/<coverable lines added or modified> * 100%

1 Codacy didn't receive coverage data for the commit, or there was an error processing the received data. Check your integration for errors and validate that your coverage setup is correct.

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.

Offset pagination is emulated by fetching from+size and slicing, and
the per-space fan-out multiplies that. Documented as accepted debt at
both places, pointing to cursor pagination via the unused page_token
fields as the designated fix.
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.
Sortable is every field that is indexed as a scalar and carried on the
match entity: name, size, lastModifiedDateTime, mimeType and the scalar
facet fields (photo.*, audio.*, image.*, location.*, ...). Both sets
are derived by reflection, so new facet fields become sortable
automatically. Multivalued fields (tags), bare facets and internal
index fields are rejected with invalidRequest at the graph layer.
CompareMatches provides the merge comparator for the service layer.
The fan-out passes order_by through to each engine query; the merge
re-sorts the combined matches with CompareMatches and keeps the score
as tiebreaker (and as the sole criterion when no order_by is given).
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.
The backends sort Name by its lowercased index term; the cross-space
merge now compares the same way so backend order survives the merge.
Case-preserved fields (audio.artist, ...) keep byte order.
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.
@dschmidt
dschmidt force-pushed the feat/search-sort-properties branch from e443b80 to cc497cc Compare August 12, 2026 23:08
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