feat(search): graph search query endpoint with aggregations - #3211
feat(search): graph search query endpoint with aggregations#3211dschmidt wants to merge 12 commits into
Conversation
Up to standards ✅🟢 Issues
|
| Metric | Results |
|---|---|
| Complexity | 446 |
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.
Follow-up: narrow
|
1b61ef6 to
fb1e41b
Compare
c54ffe7 to
cc3e6f4
Compare
cc3e6f4 to
af951f6
Compare
08eddc9 to
ceb7df5
Compare
2513263 to
71ca404
Compare
…egations Rebased dschmidt/libre-graph-api feat/graph-search-full (PR #34) onto opencloud-eu main and regenerated via the repo's woodpecker build-go recipe (openapi-generator v7.23.0, --api-name-suffix Api).
Adds the graph /v1beta1/search/query endpoint, the aggregation proto messages, the service-layer aggregation forwarding/merging, and the recursive bleve aggregation implementation (terms, range, metric, sub-aggregations).
Implements terms, range, metric and sub-aggregations for the OpenSearch backend via a dedicated aggs builder, wiring them through the shared search service.
Range aggregations parsed from/to with ParseFloat only, so date bounds on datetime fields like photo.takenDateTime silently degraded to unbounded numeric ranges. Detect date-formatted bounds (RFC3339 or YYYY-MM-DD), switch the facet to bleve date ranges and read DateRanges from the facet result. Malformed bounds in date mode are rejected.
Metric aggregations (sum/min/max/avg) only worked as sub-aggregations under a terms bucket. Compute top-level metrics by folding the matched hits through the existing accumulator and allow them through the graph layer's numeric field validation.
The cross-space merge only carried buckets, dropping metric results (value/metricKind) from the per-space responses. Reduce metrics with their kind's reducer, keyed by field and kind.
Regenerate the vendored libre-graph-api-go from the feat/search spec (metricDefinition/searchMetric, @libre.graph.subAggregations, aggregationFilterToken) and add aggregation_filters plus the permissionsActionsAllowedValues entity field to the search protos.
Migrate the graph search query to metricDefinition/searchMetric and the @libre.graph prefixes. Add the aggregationFilterToken round-trip: encode terms/range/or tokens on the response, pass aggregationFilters 1:1 to the search service, decode them and force exact case-sensitive matches in both backends. Map the WebDAV-report facets onto search hits: tags, video, motionPhoto, livePhoto, allowedValues (from the space permission set), me.following (favorite), webUrl (private link, shared helper) and thumbnails via opt-in $expand.
Bleve has count facets only: no metric and no nested facet. So far a metric or a sub-aggregation widened the page to every match and loaded all stored fields of each, then folded the hits in Go. The stored document, extracted text included, was decoded for every match: about 1s and 780MB per 100k matches, independent of the nesting depth. Metrics and nested aggregations now go through an aggCollector hooked into bleve's collector walk via the document-match-handler context key. For every match it visits the doc values of the aggregated fields, the columnar storage bleve's own facets read, and folds them into an accumulator tree. The page stays the size the caller asked for and no stored field is loaded for an aggregation: 7x faster and 80x less memory at 100k matches, within 1.4x of a native bleve facet. Flat terms and range aggregations stay bleve facets. A range parent now carries its sub-aggregations too (the hit fold matched range bucket names against raw values and never attached them), and multi-valued fields count each value like a bleve facet does. The parity suite renders nested results and pins them on both engines: terms in terms, metrics per bucket, terms in numeric and date ranges, three levels, a page of one still aggregating every match, and a malformed bound in a nested range.
fef1116 to
7f7ecbf
Compare
This contains a huge libre-graph-api-go bump - so please don't be alarmed about the size of the diff
MS-Graph-style
POST /graph/v1beta1/search/querywith terms, range, metric and nested sub-aggregations, on both the bleve and OpenSearch backends.Stacked on #3198.
Caveats
libre-graph-api-gois interim, generated from feat: add search query endpoint with request examples libre-graph-api#34 rebased onto main. Proper path: land that spec PR upstream (feat: add search query endpoint with request examples libre-graph-api#34) and pin a released version.artist -> album -> sum(duration)).Note
Even once this PR and #3210 (honest has-preview + thumbnails relationship) are both merged, search hits still won't carry thumbnails — the
$expand=thumbnailswiring for/search/queryhits builds on both PRs and currently only exists on the consolidation branch (dschmidt/opencloud@feat/graph-search-full-2, commit0d94199a:searchEntityThumbnailSetinsearchquery.go, preview presence viathumbnail.HasPreviewForMimeType+ indexedoc.preview/image-facet dimensions). It needs a follow-up PR once both are in.