1
0
mirror of https://github.com/redis/go-redis.git synced 2026-10-24 07:59:20 +03:00
Files
go-redis/example/search-aggregate-collect
ump45nose 5c913d4bd9 docs(example): drop the no-op UnstableResp3 advice (#4123)
Both FT.AGGREGATE examples tell the reader to set `UnstableResp3: true` to
use RESP3:

  example/search-aggregate-steps/README.md:15-17
  example/search-aggregate-collect/README.md:15-18

That advice is stale in two ways. `Options.UnstableResp3` is deprecated and
documented as a no-op (`options.go:448-451`, and the same note on
`universal.go`, `osscluster.go`, `ring.go`, `sentinel.go`); README.md:536-543
says plainly that "new code should not set it". Grepping the package shows the
field is only ever copied between option structs (`universal.go:291`,
`osscluster.go:514`, `ring.go:276`, `sentinel.go:255`) or assigned from a URL
(`sentinel.go:507`) — nothing reads it, so following the advice would change
nothing.

The stated reason is also gone: RediSearch RESP3 parsing has been stable since
v9.20, which is why no flag is needed. The examples still construct their
client with `Protocol: 2` (`search-aggregate-steps/main.go:25`,
`search-aggregate-collect/main.go:29`); that choice is left alone, only the
justification is corrected.
2026-10-19 14:23:47 +03:00
..

FT.AGGREGATE COLLECT reducer example

This example demonstrates the COLLECT reducer for FT.AGGREGATE: a GROUPBY reducer that, within each group, projects a chosen set of fields from every row — optionally deduplicated, sorted and limited — and returns them as an array of per-entry maps under the reducer alias. A single aggregation can therefore return each group and its top-N members.

Prerequisites

Redis 8.8+ with the Search module, listening on localhost:6379. COLLECT is gated behind unstable search features; the example enables the gate itself with CONFIG SET search-enable-unstable-features yes.

The client is configured with Protocol: 2. RESP3 needs no extra flag for FT.AGGREGATE: its response is parsed into the same typed results on both protocols. AggregateRow.Collect decodes both the RESP2 and RESP3 entry shapes, so no other code changes are needed.

Run

go run .

The example:

  1. Creates an index idx:products over hashes prefixed with product:.
  2. Seeds 10 products with name, category, brand, price, rating.
  3. Runs two aggregations:
    • Top-2 per category (options struct) — GROUPBY @category with REDUCE COLLECT ... FIELDS 2 @name @price SORTBY 2 @rating DESC LIMIT 0 2, built with redis.NewCollectReducer next to a plain COUNT reducer.
    • Whole documents per brand (builder) — LOAD * → GROUPBY @brand → COLLECT FIELDS *, expressed with the fluent AggregateBuilder.Collect. (On current unstable server builds, SORTBY combined with FIELDS * drops the sort field from the entries — sort with an explicit field list instead, as in the first query.)

Replies are decoded with AggregateRow.Collect, which returns the collected entries as []map[string]interface{} regardless of protocol.