Skip to content

feat(core): per-parent limiting for populated collections#7370

Merged
B4nan merged 2 commits intonextfrom
feat/populate-limit
Apr 18, 2026
Merged

feat(core): per-parent limiting for populated collections#7370
B4nan merged 2 commits intonextfrom
feat/populate-limit

Conversation

@B4nan
Copy link
Copy Markdown
Member

@B4nan B4nan commented Mar 21, 2026

Summary

  • Adds limit, offset, and orderBy to populateHints for per-parent collection limiting (e.g., "4 most recent posts per user")
  • SQL: uses ROW_NUMBER() OVER (PARTITION BY <fk> ORDER BY ...) wrapped in a subquery
  • MongoDB: uses $group/$push/$slice aggregation pipeline
  • Limited collections are marked partial + readonly (prevents UoW from deleting unloaded items)
  • JOINED strategy is automatically forced to SELECT_IN when limit is set
const users = await em.find(User, {}, {
  populate: ['posts'],
  populateHints: {
    posts: { limit: 4, orderBy: { createdAt: 'desc' } },
  },
});

Closes #1059

🤖 Generated with Claude Code

@codecov
Copy link
Copy Markdown

codecov bot commented Mar 21, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 99.65%. Comparing base (c3020bd) to head (7299143).
⚠️ Report is 1 commits behind head on next.

Additional details and impacted files
@@           Coverage Diff            @@
##             next    #7370    +/-   ##
========================================
  Coverage   99.65%   99.65%            
========================================
  Files         265      265            
  Lines       27308    27384    +76     
  Branches     7076     7562   +486     
========================================
+ Hits        27214    27290    +76     
  Misses         88       88            
  Partials        6        6            

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@B4nan B4nan force-pushed the feat/populate-limit branch from cdfd0a9 to 2c6de2c Compare March 21, 2026 20:33
@B4nan B4nan force-pushed the feat/populate-limit branch 2 times, most recently from 8875833 to 607b961 Compare April 1, 2026 14:53
@B4nan B4nan force-pushed the feat/populate-limit branch 2 times, most recently from 15b9edc to ef4607f Compare April 18, 2026 15:30
@B4nan B4nan changed the base branch from master to next April 18, 2026 15:30
@B4nan B4nan force-pushed the feat/populate-limit branch from ef4607f to c8fb7a8 Compare April 18, 2026 16:00
B4nan and others added 2 commits April 18, 2026 18:40
…ulateHints

When populating to-many relations, all children are loaded for every parent.
This adds `limit`, `offset`, and `orderBy` options to `populateHints`, enabling
efficient per-parent limiting using `ROW_NUMBER()` window functions for SQL
drivers and a `$group`/`$slice` aggregation pipeline for MongoDB.

Limited collections are marked as partial and readonly to prevent the UoW from
treating unloaded items as removals. JOINED strategy is automatically forced to
SELECT_IN when a limit is set.

Closes #1059

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Extend the populate-limit suites to exercise code paths that the initial
tests did not reach: pivot-table M:N populate without a limit, a nested
populate where the limit lives on the child only, a limit without any
orderBy (so the OVER clause falls back to partitioning), null/undefined
hint values being ignored, and Mongo M:N in both mappedBy and owning-
side branches of initializeManyToMany.
@B4nan B4nan force-pushed the feat/populate-limit branch from c8fb7a8 to 7299143 Compare April 18, 2026 16:40
@B4nan B4nan merged commit 6b0e006 into next Apr 18, 2026
20 checks passed
@B4nan B4nan deleted the feat/populate-limit branch April 18, 2026 17:16
B4nan added a commit that referenced this pull request Apr 19, 2026
## Summary

- Adds `limit`, `offset`, and `orderBy` to `populateHints` for
per-parent collection limiting (e.g., "4 most recent posts per user")
- SQL: uses `ROW_NUMBER() OVER (PARTITION BY <fk> ORDER BY ...)` wrapped
in a subquery
- MongoDB: uses `$group`/`$push`/`$slice` aggregation pipeline
- Limited collections are marked partial + readonly (prevents UoW from
deleting unloaded items)
- JOINED strategy is automatically forced to SELECT_IN when limit is set

```ts
const users = await em.find(User, {}, {
  populate: ['posts'],
  populateHints: {
    posts: { limit: 4, orderBy: { createdAt: 'desc' } },
  },
});
```

Closes #1059

🤖 Generated with [Claude Code](https://claude.ai/code)

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
B4nan added a commit that referenced this pull request Apr 20, 2026
## Summary

- Adds `limit`, `offset`, and `orderBy` to `populateHints` for
per-parent collection limiting (e.g., "4 most recent posts per user")
- SQL: uses `ROW_NUMBER() OVER (PARTITION BY <fk> ORDER BY ...)` wrapped
in a subquery
- MongoDB: uses `$group`/`$push`/`$slice` aggregation pipeline
- Limited collections are marked partial + readonly (prevents UoW from
deleting unloaded items)
- JOINED strategy is automatically forced to SELECT_IN when limit is set

```ts
const users = await em.find(User, {}, {
  populate: ['posts'],
  populateHints: {
    posts: { limit: 4, orderBy: { createdAt: 'desc' } },
  },
});
```

Closes #1059

🤖 Generated with [Claude Code](https://claude.ai/code)

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Use findOptions with em.populate()

1 participant