Auto-indexing service and GraphQL API for AT Protocol Records
quickslice.slices.network/
atproto
gleam
graphql
1# Aggregations
2
3Every record type has an aggregation query: `{collectionName}Aggregated`. For example, aggregate `fm.teal.alpha.feed.play` records with `fmTealAlphaFeedPlayAggregated`.
4
5Aggregation queries are public; no authentication required.
6
7## Basic Aggregation
8
9Group by a field to count occurrences:
10
11```graphql
12query {
13 fmTealAlphaFeedPlayAggregated(groupBy: [{ field: artists }]) {
14 artists
15 count
16 }
17}
18```
19
20```json
21{
22 "data": {
23 "fmTealAlphaFeedPlayAggregated": [
24 { "artists": [{ "artistName": "Radiohead" }], "count": 142 },
25 { "artists": [{ "artistName": "Boards of Canada" }], "count": 87 }
26 ]
27 }
28}
29```
30
31## Filtering & Sorting
32
33Use `where` to filter records, `orderBy` to sort by count, and `limit` to cap results.
34
35Get a user's top 10 artists for 2025:
36
37```graphql
38query {
39 fmTealAlphaFeedPlayAggregated(
40 groupBy: [{ field: artists }]
41 where: {
42 actorHandle: { eq: "baileytownsend.dev" }
43 playedTime: { gte: "2025-01-01T00:00:00Z", lt: "2026-01-01T00:00:00Z" }
44 }
45 orderBy: { count: DESC }
46 limit: 10
47 ) {
48 artists
49 count
50 }
51}
52```
53
54```json
55{
56 "data": {
57 "fmTealAlphaFeedPlayAggregated": [
58 { "artists": [{ "artistName": "Radiohead" }], "count": 142 },
59 { "artists": [{ "artistName": "Boards of Canada" }], "count": 87 }
60 ]
61 }
62}
63```
64
65## Multiple Fields
66
67Group by multiple fields. Get top tracks with their artists:
68
69```graphql
70query {
71 fmTealAlphaFeedPlayAggregated(
72 groupBy: [{ field: trackName }, { field: artists }]
73 where: {
74 actorHandle: { eq: "baileytownsend.dev" }
75 playedTime: { gte: "2025-01-01T00:00:00Z", lt: "2026-01-01T00:00:00Z" }
76 }
77 orderBy: { count: DESC }
78 limit: 10
79 ) {
80 trackName
81 artists
82 count
83 }
84}
85```
86
87```json
88{
89 "data": {
90 "fmTealAlphaFeedPlayAggregated": [
91 { "trackName": "Everything In Its Right Place", "artists": [{ "artistName": "Radiohead" }], "count": 23 },
92 { "trackName": "Roygbiv", "artists": [{ "artistName": "Boards of Canada" }], "count": 18 }
93 ]
94 }
95}
96```
97
98## Date Truncation
99
100Group datetime fields by time intervals: `HOUR`, `DAY`, `WEEK`, or `MONTH`.
101
102Get plays per month:
103
104```graphql
105query {
106 fmTealAlphaFeedPlayAggregated(
107 groupBy: [{ field: playedTime, interval: MONTH }]
108 where: {
109 actorHandle: { eq: "baileytownsend.dev" }
110 playedTime: { gte: "2025-01-01T00:00:00Z", lt: "2026-01-01T00:00:00Z" }
111 }
112 orderBy: { count: DESC }
113 ) {
114 playedTime
115 count
116 }
117}
118```
119
120```json
121{
122 "data": {
123 "fmTealAlphaFeedPlayAggregated": [
124 { "playedTime": "2025-03-01", "count": 847 },
125 { "playedTime": "2025-01-01", "count": 623 },
126 { "playedTime": "2025-02-01", "count": 598 }
127 ]
128 }
129}
130```
131
132## Reference
133
134### Query Structure
135
136- `{collectionName}Aggregated` - Aggregation query for any record type
137- `groupBy` (required) - Array of fields to group by, with optional `interval` for datetime fields
138- `where` (optional) - Filter conditions
139- `orderBy` (optional) - Sort by `count` (`ASC` or `DESC`)
140- `limit` (optional) - Maximum groups to return (default: 100)
141
142### Available Columns
143
144Beyond record fields, group by: `uri`, `cid`, `did`, `collection`, `indexedAt`, `actorHandle`
145
146### Validation
147
148- Date intervals can only be applied to datetime fields
149- Maximum 5 groupBy fields per query