Releases: rush-db/rushdb
@rushdb/javascript-sdk@1.15.2
Patch Changes
- 9b25c07: Make int txn optionally closed after commit
@rushdb/javascript-sdk@1.15.1
Patch Changes
- 954ab72: Fix ts bug in aggregations
@rushdb/javascript-sdk@1.15.0
Minor Changes
-
7f19708: ## Summary
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.
✨ New Feature:
groupByClauseYou can now pivot / summarize search results by one or more keys. Keys reference an alias + property (root alias is implicitly
$record).Example (JS SDK):
const dealsByStage = await db.records.find({ labels: ['HS_DEAL'], aggregate: { count: { fn: 'count', alias: '$record' }, avgAmount: { fn: 'avg', field: 'amount', alias: '$record' } }, groupBy: ['$record.dealstage'], orderBy: { count: 'desc' } }) // → rows like: [{ dealstage: 'prospecting', count: 120, avgAmount: 3400 }, ...]
Key capabilities:
- Multiple grouping keys:
groupBy: ['$record.category', '$record.active'] - Group by related aliases (declare alias in
wheretraversal first) - Works with all existing aggregation functions (count, sum, avg, min, max, collect, similarity, etc.)
- Ordering applies to aggregated rows when
groupByis present - Requires at least one aggregation entry to take effect
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 viacollect).
🔄 Aggregation & Semantics Updates
collectresults are unique by default. Setunique: falseto retain duplicates.- Aggregation entries now consistently use the
uniqueflag (replacing legacyuniq). - Distinct handling for grouped queries unified under the
uniqueoption. - Improved Cypher generation: clearer alias usage and property quoting; vector similarity function formatting tightened.
- Added internal
PROPERTY_WILDCARD_PROJECTIONsupport (enables future selective projections) – not yet a public API, but impacts generated queries.
💥 Breaking Changes
Area Change Action Required Schema field definitions uniqkey renamed touniqueRename all occurrences ( { uniq: true }→{ unique: true }).Aggregation definitions Aggregator option uniqrenamed touniqueUpdate custom aggregation objects ( uniq: false→unique: false).Result shape (when using groupBy)Raw record objects no longer returned automatically If you previously expected full records, add a collectaggregation (e.g.rows: { fn: 'collect', alias: '$record' }).Default uniqueness for collectNow unique by default Add unique: falseif you require duplicates.Internal alias constant DEFAULT_RECORD_ALIAS→ROOT_RECORD_ALIASOnly relevant if you referenced internal constants (avoid relying on these). 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.
🛠 Migration Guide
- Rename all schema property options:
- Before:
email: { type: 'string', uniq: true } - After:
email: { type: 'string', unique: true }
- Before:
- Update aggregation specs:
- Before:
names: { fn: 'collect', field: 'name', alias: '$user', uniq: true } - After:
names: { fn: 'collect', field: 'name', alias: '$user' }(omituniqueif true)
- Before:
- Reintroduce duplicate collection (if needed): add
unique: false. - When adopting
groupBy, ensure at least one aggregation is defined; queries with onlygroupByare invalid. - Adjust consumer code to handle aggregated row shape instead of full record instances.
- For hierarchical drill‑downs: group at the parent level; use nested
collectfor children instead of adding child keys togroupBy.
Example Migration (JS)
aggregate: { - employeeNames: { fn: 'collect', field: 'name', alias: '$employee', uniq: true }, + employeeNames: { fn: 'collect', field: 'name', alias: '$employee' }, }Adding Grouping
const deptProjects = await db.records.find({ labels: ['DEPARTMENT'], where: { PROJECT: { $alias: '$project' } }, aggregate: { projectCount: { fn: 'count', alias: '$project' }, projects: { fn: 'collect', field: 'name', alias: '$project', unique: true } }, groupBy: ['$record.name'], orderBy: { projectCount: 'desc' } })
📘 Documentation
- Added dedicated concept page:
concepts/search/group-bycentralizing all grouping patterns (multi-key, alias-based, nested, uniqueness nuances, limitations). - Updated Python, REST, and TypeScript SDK "Get Records" guides with concise grouping sections linking to the concept page.
- Refactored Aggregations doc to avoid duplication and point to new grouping guide.
- Standardized examples to use
uniqueterminology.
🧪 Tests & Internal Refactors
- Extended aggregate & query builder tests to cover
groupBypermutations (single key, multi-key, alias grouping, collect uniqueness flags). - Parser adjustments for: property quoting, alias resolution, vector similarity formatting, optional matches, and root alias constant rename.
- Introduced
AggregateContextenhancements to track grouping state.
⚠️ Edge Cases & Notes- An empty
groupByarray is ignored; supply at least one key. - Supplying a group key for a property that does not exist yields rows with
nullfor that column (consistent with underlying graph behavior) – validate upstream if needed. - Ordering by an aggregation that isn't defined will be rejected; always define the aggregate you sort by.
- To sort by a group key, just reference it in
orderByusing the property name (without alias prefix) after grouping.
✅ Quick Checklist
Task Done? Renamed all uniq→uniquein schema & aggregationsReviewed any collectaggregations for unintended de-duplicationAdded unique: falsewhere duplicates are requiredUpdated UI / API consumers for aggregated row shape under groupByAdded collectfields if raw record snapshots are still neededAdded / validated ordering under grouped queries
Feedback
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.
TL;DR
Use
groupBy+aggregateto pivot results; renameuniq→unique;collectis now unique by default; aggregated queries return row sets, not raw records. - Multiple grouping keys:
@rushdb/javascript-sdk@1.14.2
Patch Changes
- 63823d0: Optimize DbContextMiddleware
@rushdb/javascript-sdk@1.14.1
Patch Changes
- 9cafe44: Transactions management improvements
@rushdb/javascript-sdk@1.14.0
Minor Changes
- 7cd984c: Added
records.importCsvmethod with configurable CSVparseConfigand extended import docs.
@rushdb/javascript-sdk@1.13.2
Patch Changes
- ed6063d: Fix missmatching transaction in import service
@rushdb/javascript-sdk@1.13.1
Patch Changes
- 2e89930: Safely handling properties with spaces in name
@rushdb/javascript-sdk@1.13.0
Minor Changes
- 2b76c22: Add raw cypher query support
@rushdb/javascript-sdk@1.12.1
Patch Changes
- d55ae51: Escape stringified JSON characters fix