Skip to content

Commit 3a0ec43

Browse files
authored
Merge pull request #258 from rush-db/changeset-release/main
chore(release): version packages v1.15.0
2 parents 2181e02 + b5a7f1f commit 3a0ec43

File tree

11 files changed

+775
-136
lines changed

11 files changed

+775
-136
lines changed

.changeset/modern-masks-film.md

Lines changed: 0 additions & 131 deletions
This file was deleted.

docs/CHANGELOG.md

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,157 @@
11
# rushdb-docs
22

3+
## 1.15.0
4+
5+
### Minor Changes
6+
7+
- 7f19708: ## Summary
8+
Adds first-class grouping support to the Search API (`groupBy`) across core, JavaScript SDK, dashboard, website, and docs. Also standardizes terminology (`uniq` -> `unique`), refines aggregation semantics, and updates documentation with a dedicated grouping concept page.
9+
10+
***
11+
12+
## ✨ New Feature: `groupBy` Clause
13+
14+
You can now pivot / summarize search results by one or more keys. Keys reference an alias + property (root alias is implicitly `$record`).
15+
16+
Example (JS SDK):
17+
18+
```ts
19+
const dealsByStage = await db.records.find({
20+
labels: ['HS_DEAL'],
21+
aggregate: {
22+
count: { fn: 'count', alias: '$record' },
23+
avgAmount: { fn: 'avg', field: 'amount', alias: '$record' }
24+
},
25+
groupBy: ['$record.dealstage'],
26+
orderBy: { count: 'desc' }
27+
})
28+
// → rows like: [{ dealstage: 'prospecting', count: 120, avgAmount: 3400 }, ...]
29+
```
30+
31+
Key capabilities:
32+
33+
- Multiple grouping keys: `groupBy: ['$record.category', '$record.active']`
34+
- Group by related aliases (declare alias in `where` traversal first)
35+
- Works with all existing aggregation functions (count, sum, avg, min, max, collect, similarity, etc.)
36+
- Ordering applies to aggregated rows when `groupBy` is present
37+
- Requires at least one aggregation entry to take effect
38+
39+
Result shape when using `groupBy`: each row contains only the grouping fields plus aggregated fields (raw record bodies are not returned unless you also aggregate them via `collect`).
40+
41+
***
42+
43+
## 🔄 Aggregation & Semantics Updates
44+
45+
- `collect` results are unique by default. Set `unique: false` to retain duplicates.
46+
- Aggregation entries now consistently use the `unique` flag (replacing legacy `uniq`).
47+
- Distinct handling for grouped queries unified under the `unique` option.
48+
- Improved Cypher generation: clearer alias usage and property quoting; vector similarity function formatting tightened.
49+
- Added internal `PROPERTY_WILDCARD_PROJECTION` support (enables future selective projections) – not yet a public API, but impacts generated queries.
50+
51+
***
52+
53+
## 💥 Breaking Changes
54+
55+
| Area | Change | Action Required |
56+
| ----------------------------------- | --------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
57+
| Schema field definitions | `uniq` key renamed to `unique` | Rename all occurrences (`{ uniq: true }``{ unique: true }`). |
58+
| Aggregation definitions | Aggregator option `uniq` renamed to `unique` | Update custom aggregation objects (`uniq: false``unique: false`). |
59+
| Result shape (when using `groupBy`) | Raw record objects no longer returned automatically | If you previously expected full records, add a `collect` aggregation (e.g. `rows: { fn: 'collect', alias: '$record' }`). |
60+
| Default uniqueness for `collect` | Now unique by default | Add `unique: false` if you require duplicates. |
61+
| Internal alias constant | `DEFAULT_RECORD_ALIAS``ROOT_RECORD_ALIAS` | Only relevant if you referenced internal constants (avoid relying on these). |
62+
63+
If any code or saved JSON queries still send `uniq`, they will now fail unless a compatibility shim exists (none added in this release). Treat this as a required migration.
64+
65+
***
66+
67+
## 🛠 Migration Guide
68+
69+
1. Rename all schema property options:
70+
- Before: `email: { type: 'string', uniq: true }`
71+
- After: `email: { type: 'string', unique: true }`
72+
2. Update aggregation specs:
73+
- Before: `names: { fn: 'collect', field: 'name', alias: '$user', uniq: true }`
74+
- After: `names: { fn: 'collect', field: 'name', alias: '$user' }` (omit `unique` if true)
75+
3. Reintroduce duplicate collection (if needed): add `unique: false`.
76+
4. When adopting `groupBy`, ensure at least one aggregation is defined; queries with only `groupBy` are invalid.
77+
5. Adjust consumer code to handle aggregated row shape instead of full record instances.
78+
6. For hierarchical drill‑downs: group at the parent level; use nested `collect` for children instead of adding child keys to `groupBy`.
79+
80+
### Example Migration (JS)
81+
82+
```diff
83+
aggregate: {
84+
- employeeNames: { fn: 'collect', field: 'name', alias: '$employee', uniq: true },
85+
+ employeeNames: { fn: 'collect', field: 'name', alias: '$employee' },
86+
}
87+
```
88+
89+
### Adding Grouping
90+
91+
```ts
92+
const deptProjects = await db.records.find({
93+
labels: ['DEPARTMENT'],
94+
where: { PROJECT: { $alias: '$project' } },
95+
aggregate: {
96+
projectCount: { fn: 'count', alias: '$project' },
97+
projects: { fn: 'collect', field: 'name', alias: '$project', unique: true }
98+
},
99+
groupBy: ['$record.name'],
100+
orderBy: { projectCount: 'desc' }
101+
})
102+
```
103+
104+
***
105+
106+
## 📘 Documentation
107+
108+
- Added dedicated concept page: `concepts/search/group-by` centralizing all grouping patterns (multi-key, alias-based, nested, uniqueness nuances, limitations).
109+
- Updated Python, REST, and TypeScript SDK "Get Records" guides with concise grouping sections linking to the concept page.
110+
- Refactored Aggregations doc to avoid duplication and point to new grouping guide.
111+
- Standardized examples to use `unique` terminology.
112+
113+
***
114+
115+
## 🧪 Tests & Internal Refactors
116+
117+
- Extended aggregate & query builder tests to cover `groupBy` permutations (single key, multi-key, alias grouping, collect uniqueness flags).
118+
- Parser adjustments for: property quoting, alias resolution, vector similarity formatting, optional matches, and root alias constant rename.
119+
- Introduced `AggregateContext` enhancements to track grouping state.
120+
121+
***
122+
123+
## ⚠️ Edge Cases & Notes
124+
125+
- An empty `groupBy` array is ignored; supply at least one key.
126+
- Supplying a group key for a property that does not exist yields rows with `null` for that column (consistent with underlying graph behavior) – validate upstream if needed.
127+
- Ordering by an aggregation that isn't defined will be rejected; always define the aggregate you sort by.
128+
- To sort by a group key, just reference it in `orderBy` using the property name (without alias prefix) after grouping.
129+
130+
***
131+
132+
## ✅ Quick Checklist
133+
134+
| Task | Done? |
135+
| ------------------------------------------------------------------- | ----- |
136+
| Renamed all `uniq``unique` in schema & aggregations | |
137+
| Reviewed any `collect` aggregations for unintended de-duplication | |
138+
| Added `unique: false` where duplicates are required | |
139+
| Updated UI / API consumers for aggregated row shape under `groupBy` | |
140+
| Added `collect` fields if raw record snapshots are still needed | |
141+
| Added / validated ordering under grouped queries | |
142+
143+
***
144+
145+
## Feedback
146+
147+
Please report any unexpected behavior with grouped queries (especially multi-key or alias-based grouping) so we can refine edge case handling in upcoming releases.
148+
149+
***
150+
151+
## TL;DR
152+
153+
Use `groupBy` + `aggregate` to pivot results; rename `uniq``unique`; `collect` is now unique by default; aggregated queries return row sets, not raw records.
154+
3155
## 1.14.2
4156

5157
### Patch Changes

docs/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "rushdb-docs",
3-
"version": "1.14.2",
3+
"version": "1.15.0",
44
"private": true,
55
"license": "Apache-2.0",
66
"scripts": {

0 commit comments

Comments
 (0)