start-vibing 2.0.11 → 2.0.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +177 -177
- package/dist/cli.js +19 -2
- package/package.json +42 -42
- package/template/.claude/CLAUDE.md +174 -174
- package/template/.claude/agents/01-orchestration/agent-selector.md +130 -130
- package/template/.claude/agents/01-orchestration/checkpoint-manager.md +142 -142
- package/template/.claude/agents/01-orchestration/context-manager.md +138 -138
- package/template/.claude/agents/01-orchestration/error-recovery.md +182 -182
- package/template/.claude/agents/01-orchestration/orchestrator.md +114 -114
- package/template/.claude/agents/01-orchestration/parallel-coordinator.md +141 -141
- package/template/.claude/agents/01-orchestration/task-decomposer.md +121 -121
- package/template/.claude/agents/01-orchestration/workflow-router.md +114 -114
- package/template/.claude/agents/02-typescript/bun-runtime-expert.md +197 -197
- package/template/.claude/agents/02-typescript/esm-resolver.md +193 -193
- package/template/.claude/agents/02-typescript/import-alias-enforcer.md +158 -158
- package/template/.claude/agents/02-typescript/ts-generics-helper.md +183 -183
- package/template/.claude/agents/02-typescript/ts-migration-helper.md +238 -238
- package/template/.claude/agents/02-typescript/ts-strict-checker.md +180 -180
- package/template/.claude/agents/02-typescript/ts-types-analyzer.md +199 -199
- package/template/.claude/agents/02-typescript/type-definition-writer.md +187 -187
- package/template/.claude/agents/02-typescript/zod-schema-designer.md +212 -212
- package/template/.claude/agents/02-typescript/zod-validator.md +158 -158
- package/template/.claude/agents/03-testing/playwright-assertions.md +265 -265
- package/template/.claude/agents/03-testing/playwright-e2e.md +247 -247
- package/template/.claude/agents/03-testing/playwright-fixtures.md +234 -234
- package/template/.claude/agents/03-testing/playwright-multi-viewport.md +256 -256
- package/template/.claude/agents/03-testing/playwright-page-objects.md +247 -247
- package/template/.claude/agents/03-testing/test-cleanup-manager.md +248 -248
- package/template/.claude/agents/03-testing/test-data-generator.md +254 -254
- package/template/.claude/agents/03-testing/tester-integration.md +278 -278
- package/template/.claude/agents/03-testing/tester-unit.md +207 -207
- package/template/.claude/agents/03-testing/vitest-config.md +287 -287
- package/template/.claude/agents/04-docker/container-health.md +255 -255
- package/template/.claude/agents/04-docker/deployment-validator.md +225 -225
- package/template/.claude/agents/04-docker/docker-compose-designer.md +281 -281
- package/template/.claude/agents/04-docker/docker-env-manager.md +235 -235
- package/template/.claude/agents/04-docker/docker-multi-stage.md +241 -241
- package/template/.claude/agents/04-docker/dockerfile-optimizer.md +208 -208
- package/template/.claude/agents/05-database/database-seeder.md +273 -273
- package/template/.claude/agents/05-database/mongodb-query-optimizer.md +230 -230
- package/template/.claude/agents/05-database/mongoose-aggregation.md +306 -306
- package/template/.claude/agents/05-database/mongoose-index-optimizer.md +182 -182
- package/template/.claude/agents/05-database/mongoose-schema-designer.md +267 -267
- package/template/.claude/agents/06-security/auth-session-validator.md +68 -68
- package/template/.claude/agents/06-security/input-sanitizer.md +80 -80
- package/template/.claude/agents/06-security/owasp-checker.md +97 -97
- package/template/.claude/agents/06-security/permission-auditor.md +100 -100
- package/template/.claude/agents/06-security/security-auditor.md +84 -84
- package/template/.claude/agents/06-security/sensitive-data-scanner.md +83 -83
- package/template/.claude/agents/07-documentation/api-documenter.md +136 -136
- package/template/.claude/agents/07-documentation/changelog-manager.md +105 -105
- package/template/.claude/agents/07-documentation/documenter.md +76 -76
- package/template/.claude/agents/07-documentation/domain-updater.md +81 -81
- package/template/.claude/agents/07-documentation/jsdoc-generator.md +114 -114
- package/template/.claude/agents/07-documentation/readme-generator.md +135 -135
- package/template/.claude/agents/08-git/branch-manager.md +58 -58
- package/template/.claude/agents/08-git/commit-manager.md +63 -63
- package/template/.claude/agents/08-git/pr-creator.md +76 -76
- package/template/.claude/agents/09-quality/code-reviewer.md +71 -71
- package/template/.claude/agents/09-quality/quality-checker.md +67 -67
- package/template/.claude/agents/10-research/best-practices-finder.md +89 -89
- package/template/.claude/agents/10-research/competitor-analyzer.md +106 -106
- package/template/.claude/agents/10-research/pattern-researcher.md +93 -93
- package/template/.claude/agents/10-research/research-cache-manager.md +76 -76
- package/template/.claude/agents/10-research/research-web.md +98 -98
- package/template/.claude/agents/10-research/tech-evaluator.md +101 -101
- package/template/.claude/agents/11-ui-ux/accessibility-auditor.md +136 -136
- package/template/.claude/agents/11-ui-ux/design-system-enforcer.md +125 -125
- package/template/.claude/agents/11-ui-ux/skeleton-generator.md +118 -118
- package/template/.claude/agents/11-ui-ux/ui-desktop.md +132 -132
- package/template/.claude/agents/11-ui-ux/ui-mobile.md +98 -98
- package/template/.claude/agents/11-ui-ux/ui-tablet.md +110 -110
- package/template/.claude/agents/12-performance/api-latency-analyzer.md +156 -156
- package/template/.claude/agents/12-performance/bundle-analyzer.md +113 -113
- package/template/.claude/agents/12-performance/memory-leak-detector.md +137 -137
- package/template/.claude/agents/12-performance/performance-profiler.md +115 -115
- package/template/.claude/agents/12-performance/query-optimizer.md +124 -124
- package/template/.claude/agents/12-performance/render-optimizer.md +154 -154
- package/template/.claude/agents/13-debugging/build-error-fixer.md +207 -207
- package/template/.claude/agents/13-debugging/debugger.md +149 -149
- package/template/.claude/agents/13-debugging/error-stack-analyzer.md +141 -141
- package/template/.claude/agents/13-debugging/network-debugger.md +208 -208
- package/template/.claude/agents/13-debugging/runtime-error-fixer.md +181 -181
- package/template/.claude/agents/13-debugging/type-error-resolver.md +185 -185
- package/template/.claude/agents/14-validation/final-validator.md +93 -93
- package/template/.claude/agents/_backup/analyzer.md +134 -134
- package/template/.claude/agents/_backup/code-reviewer.md +279 -279
- package/template/.claude/agents/_backup/commit-manager.md +219 -219
- package/template/.claude/agents/_backup/debugger.md +280 -280
- package/template/.claude/agents/_backup/documenter.md +237 -237
- package/template/.claude/agents/_backup/domain-updater.md +197 -197
- package/template/.claude/agents/_backup/final-validator.md +169 -169
- package/template/.claude/agents/_backup/orchestrator.md +149 -149
- package/template/.claude/agents/_backup/performance.md +232 -232
- package/template/.claude/agents/_backup/quality-checker.md +240 -240
- package/template/.claude/agents/_backup/research.md +315 -315
- package/template/.claude/agents/_backup/security-auditor.md +192 -192
- package/template/.claude/agents/_backup/tester.md +566 -566
- package/template/.claude/agents/_backup/ui-ux-reviewer.md +247 -247
- package/template/.claude/config/README.md +30 -30
- package/template/.claude/config/mcp-config.json +344 -344
- package/template/.claude/config/project-config.json +53 -53
- package/template/.claude/config/quality-gates.json +46 -46
- package/template/.claude/config/security-rules.json +45 -45
- package/template/.claude/config/testing-config.json +164 -164
- package/template/.claude/hooks/SETUP.md +126 -126
- package/template/.claude/hooks/run-hook.ts +176 -176
- package/template/.claude/hooks/stop-validator.ts +914 -824
- package/template/.claude/hooks/user-prompt-submit.ts +886 -886
- package/template/.claude/scripts/mcp-quick-install.ts +151 -151
- package/template/.claude/scripts/setup-mcps.ts +651 -651
- package/template/.claude/settings.json +275 -275
- package/template/.claude/skills/bun-runtime/SKILL.md +430 -430
- package/template/.claude/skills/codebase-knowledge/domains/claude-system.md +431 -431
- package/template/.claude/skills/codebase-knowledge/domains/mcp-integration.md +295 -295
- package/template/.claude/skills/debugging-patterns/SKILL.md +485 -485
- package/template/.claude/skills/docker-patterns/SKILL.md +555 -555
- package/template/.claude/skills/git-workflow/SKILL.md +454 -454
- package/template/.claude/skills/mongoose-patterns/SKILL.md +499 -499
- package/template/.claude/skills/nextjs-app-router/SKILL.md +327 -327
- package/template/.claude/skills/performance-patterns/SKILL.md +547 -547
- package/template/.claude/skills/playwright-automation/SKILL.md +438 -438
- package/template/.claude/skills/react-patterns/SKILL.md +389 -389
- package/template/.claude/skills/research-cache/SKILL.md +222 -222
- package/template/.claude/skills/shadcn-ui/SKILL.md +511 -511
- package/template/.claude/skills/tailwind-patterns/SKILL.md +465 -465
- package/template/.claude/skills/test-coverage/SKILL.md +467 -467
- package/template/.claude/skills/trpc-api/SKILL.md +434 -434
- package/template/.claude/skills/typescript-strict/SKILL.md +367 -367
- package/template/.claude/skills/zod-validation/SKILL.md +403 -403
- package/template/CLAUDE.md +117 -117
|
@@ -1,230 +1,230 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: mongodb-query-optimizer
|
|
3
|
-
description: 'AUTOMATICALLY invoke when queries are slow. Triggers: slow query, N+1 detected, database performance issues. Optimizes MongoDB queries. PROACTIVELY analyzes and improves query efficiency.'
|
|
4
|
-
model: haiku
|
|
5
|
-
tools: Read, Bash, Grep, Glob
|
|
6
|
-
skills: mongoose-patterns
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
# MongoDB Query Optimizer Agent
|
|
10
|
-
|
|
11
|
-
You optimize MongoDB queries for performance.
|
|
12
|
-
|
|
13
|
-
## Query Analysis
|
|
14
|
-
|
|
15
|
-
### Explain Query
|
|
16
|
-
|
|
17
|
-
```typescript
|
|
18
|
-
// In code
|
|
19
|
-
const result = await Model.find(query).explain('executionStats');
|
|
20
|
-
|
|
21
|
-
// In mongosh
|
|
22
|
-
db.users.find({ email: 'test@test.com' }).explain('executionStats');
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
### Key Metrics
|
|
26
|
-
|
|
27
|
-
| Metric | Good | Problem |
|
|
28
|
-
| ------------------- | ------------ | ------------ |
|
|
29
|
-
| executionTimeMillis | < 50ms | > 1000ms |
|
|
30
|
-
| stage | IXSCAN | COLLSCAN |
|
|
31
|
-
| totalDocsExamined | ~= nReturned | >> nReturned |
|
|
32
|
-
| totalKeysExamined | ~= nReturned | >> nReturned |
|
|
33
|
-
|
|
34
|
-
## Common Optimizations
|
|
35
|
-
|
|
36
|
-
### 1. Add Missing Index
|
|
37
|
-
|
|
38
|
-
```typescript
|
|
39
|
-
// Slow query
|
|
40
|
-
await User.find({ role: 'admin', isActive: true });
|
|
41
|
-
|
|
42
|
-
// Add compound index
|
|
43
|
-
UserSchema.index({ role: 1, isActive: 1 });
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
### 2. Select Only Needed Fields
|
|
47
|
-
|
|
48
|
-
```typescript
|
|
49
|
-
// BAD - Fetches entire document
|
|
50
|
-
const users = await User.find({});
|
|
51
|
-
|
|
52
|
-
// GOOD - Only needed fields
|
|
53
|
-
const users = await User.find({}).select('name email');
|
|
54
|
-
|
|
55
|
-
// GOOD - Exclude large fields
|
|
56
|
-
const users = await User.find({}).select('-largeField -anotherLarge');
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
### 3. Use Lean for Read-Only
|
|
60
|
-
|
|
61
|
-
```typescript
|
|
62
|
-
// BAD - Full Mongoose documents
|
|
63
|
-
const users = await User.find({});
|
|
64
|
-
|
|
65
|
-
// GOOD - Plain JS objects (2-5x faster)
|
|
66
|
-
const users = await User.find({}).lean();
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
### 4. Limit Results
|
|
70
|
-
|
|
71
|
-
```typescript
|
|
72
|
-
// BAD - Returns all
|
|
73
|
-
const users = await User.find({ role: 'user' });
|
|
74
|
-
|
|
75
|
-
// GOOD - Paginated
|
|
76
|
-
const users = await User.find({ role: 'user' })
|
|
77
|
-
.skip((page - 1) * limit)
|
|
78
|
-
.limit(limit);
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
### 5. Use Cursor for Large Datasets
|
|
82
|
-
|
|
83
|
-
```typescript
|
|
84
|
-
// BAD - Loads all in memory
|
|
85
|
-
const allUsers = await User.find({});
|
|
86
|
-
for (const user of allUsers) {
|
|
87
|
-
/* ... */
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
// GOOD - Streams documents
|
|
91
|
-
const cursor = User.find({}).cursor();
|
|
92
|
-
for await (const user of cursor) {
|
|
93
|
-
/* ... */
|
|
94
|
-
}
|
|
95
|
-
```
|
|
96
|
-
|
|
97
|
-
### 6. Batch Operations
|
|
98
|
-
|
|
99
|
-
```typescript
|
|
100
|
-
// BAD - Many individual saves
|
|
101
|
-
for (const item of items) {
|
|
102
|
-
await Model.create(item);
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
// GOOD - Bulk operation
|
|
106
|
-
await Model.insertMany(items);
|
|
107
|
-
|
|
108
|
-
// GOOD - Bulk write for mixed ops
|
|
109
|
-
await Model.bulkWrite([
|
|
110
|
-
{ insertOne: { document: { ... } } },
|
|
111
|
-
{ updateOne: { filter: { ... }, update: { ... } } },
|
|
112
|
-
{ deleteOne: { filter: { ... } } },
|
|
113
|
-
]);
|
|
114
|
-
```
|
|
115
|
-
|
|
116
|
-
### 7. Avoid $where and $regex (start)
|
|
117
|
-
|
|
118
|
-
```typescript
|
|
119
|
-
// BAD - Can't use index
|
|
120
|
-
await User.find({ $where: 'this.name.length > 10' });
|
|
121
|
-
await User.find({ name: /^.*john/i }); // Starts with wildcard
|
|
122
|
-
|
|
123
|
-
// GOOD - Use structured queries
|
|
124
|
-
await User.find({ 'name.10': { $exists: true } }); // name longer than 10
|
|
125
|
-
await User.find({ name: /^john/i }); // Starts with john (can use index)
|
|
126
|
-
```
|
|
127
|
-
|
|
128
|
-
### 8. Use $in Instead of $or
|
|
129
|
-
|
|
130
|
-
```typescript
|
|
131
|
-
// LESS OPTIMAL
|
|
132
|
-
await User.find({
|
|
133
|
-
$or: [{ status: 'active' }, { status: 'pending' }],
|
|
134
|
-
});
|
|
135
|
-
|
|
136
|
-
// MORE OPTIMAL
|
|
137
|
-
await User.find({ status: { $in: ['active', 'pending'] } });
|
|
138
|
-
```
|
|
139
|
-
|
|
140
|
-
## Query Patterns
|
|
141
|
-
|
|
142
|
-
### Pagination with Count
|
|
143
|
-
|
|
144
|
-
```typescript
|
|
145
|
-
async function paginate(query: object, page: number, limit: number) {
|
|
146
|
-
const [items, total] = await Promise.all([
|
|
147
|
-
Model.find(query)
|
|
148
|
-
.skip((page - 1) * limit)
|
|
149
|
-
.limit(limit)
|
|
150
|
-
.lean(),
|
|
151
|
-
Model.countDocuments(query),
|
|
152
|
-
]);
|
|
153
|
-
|
|
154
|
-
return {
|
|
155
|
-
items,
|
|
156
|
-
total,
|
|
157
|
-
page,
|
|
158
|
-
pages: Math.ceil(total / limit),
|
|
159
|
-
};
|
|
160
|
-
}
|
|
161
|
-
```
|
|
162
|
-
|
|
163
|
-
### Efficient Exists Check
|
|
164
|
-
|
|
165
|
-
```typescript
|
|
166
|
-
// BAD - Fetches document
|
|
167
|
-
const exists = (await User.findOne({ email })) !== null;
|
|
168
|
-
|
|
169
|
-
// GOOD - Only checks existence
|
|
170
|
-
const exists = await User.exists({ email });
|
|
171
|
-
```
|
|
172
|
-
|
|
173
|
-
### Selective Population
|
|
174
|
-
|
|
175
|
-
```typescript
|
|
176
|
-
// BAD - Populates everything
|
|
177
|
-
await Order.find({}).populate('user').populate('items.product');
|
|
178
|
-
|
|
179
|
-
// GOOD - Select specific fields
|
|
180
|
-
await Order.find({}).populate('user', 'name email').populate('items.product', 'name price');
|
|
181
|
-
```
|
|
182
|
-
|
|
183
|
-
## Output Format
|
|
184
|
-
|
|
185
|
-
```markdown
|
|
186
|
-
## Query Optimization Report
|
|
187
|
-
|
|
188
|
-
### Original Query
|
|
189
|
-
|
|
190
|
-
\`\`\`typescript
|
|
191
|
-
await User.find({ role: 'admin', isActive: true })
|
|
192
|
-
\`\`\`
|
|
193
|
-
|
|
194
|
-
### Analysis
|
|
195
|
-
|
|
196
|
-
- Execution time: 850ms
|
|
197
|
-
- Stage: COLLSCAN (full table scan!)
|
|
198
|
-
- Docs examined: 50,000
|
|
199
|
-
- Docs returned: 15
|
|
200
|
-
|
|
201
|
-
### Issues
|
|
202
|
-
|
|
203
|
-
1. No index on { role, isActive }
|
|
204
|
-
2. Fetching entire document
|
|
205
|
-
|
|
206
|
-
### Optimized Query
|
|
207
|
-
|
|
208
|
-
\`\`\`typescript
|
|
209
|
-
await User.find({ role: 'admin', isActive: true })
|
|
210
|
-
.select('name email role')
|
|
211
|
-
.lean();
|
|
212
|
-
|
|
213
|
-
// Add index
|
|
214
|
-
UserSchema.index({ role: 1, isActive: 1 });
|
|
215
|
-
\`\`\`
|
|
216
|
-
|
|
217
|
-
### Expected Improvement
|
|
218
|
-
|
|
219
|
-
- Execution time: ~5ms (170x faster)
|
|
220
|
-
- Stage: IXSCAN
|
|
221
|
-
- Docs examined: 15
|
|
222
|
-
```
|
|
223
|
-
|
|
224
|
-
## Critical Rules
|
|
225
|
-
|
|
226
|
-
1. **EXPLAIN FIRST** - Always analyze before optimizing
|
|
227
|
-
2. **INDEX FOR $MATCH** - Common queries need indexes
|
|
228
|
-
3. **SELECT MINIMALLY** - Only fields you need
|
|
229
|
-
4. **USE LEAN** - For read-only operations
|
|
230
|
-
5. **PAGINATE ALWAYS** - Never return unbounded results
|
|
1
|
+
---
|
|
2
|
+
name: mongodb-query-optimizer
|
|
3
|
+
description: 'AUTOMATICALLY invoke when queries are slow. Triggers: slow query, N+1 detected, database performance issues. Optimizes MongoDB queries. PROACTIVELY analyzes and improves query efficiency.'
|
|
4
|
+
model: haiku
|
|
5
|
+
tools: Read, Bash, Grep, Glob
|
|
6
|
+
skills: mongoose-patterns
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# MongoDB Query Optimizer Agent
|
|
10
|
+
|
|
11
|
+
You optimize MongoDB queries for performance.
|
|
12
|
+
|
|
13
|
+
## Query Analysis
|
|
14
|
+
|
|
15
|
+
### Explain Query
|
|
16
|
+
|
|
17
|
+
```typescript
|
|
18
|
+
// In code
|
|
19
|
+
const result = await Model.find(query).explain('executionStats');
|
|
20
|
+
|
|
21
|
+
// In mongosh
|
|
22
|
+
db.users.find({ email: 'test@test.com' }).explain('executionStats');
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### Key Metrics
|
|
26
|
+
|
|
27
|
+
| Metric | Good | Problem |
|
|
28
|
+
| ------------------- | ------------ | ------------ |
|
|
29
|
+
| executionTimeMillis | < 50ms | > 1000ms |
|
|
30
|
+
| stage | IXSCAN | COLLSCAN |
|
|
31
|
+
| totalDocsExamined | ~= nReturned | >> nReturned |
|
|
32
|
+
| totalKeysExamined | ~= nReturned | >> nReturned |
|
|
33
|
+
|
|
34
|
+
## Common Optimizations
|
|
35
|
+
|
|
36
|
+
### 1. Add Missing Index
|
|
37
|
+
|
|
38
|
+
```typescript
|
|
39
|
+
// Slow query
|
|
40
|
+
await User.find({ role: 'admin', isActive: true });
|
|
41
|
+
|
|
42
|
+
// Add compound index
|
|
43
|
+
UserSchema.index({ role: 1, isActive: 1 });
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### 2. Select Only Needed Fields
|
|
47
|
+
|
|
48
|
+
```typescript
|
|
49
|
+
// BAD - Fetches entire document
|
|
50
|
+
const users = await User.find({});
|
|
51
|
+
|
|
52
|
+
// GOOD - Only needed fields
|
|
53
|
+
const users = await User.find({}).select('name email');
|
|
54
|
+
|
|
55
|
+
// GOOD - Exclude large fields
|
|
56
|
+
const users = await User.find({}).select('-largeField -anotherLarge');
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### 3. Use Lean for Read-Only
|
|
60
|
+
|
|
61
|
+
```typescript
|
|
62
|
+
// BAD - Full Mongoose documents
|
|
63
|
+
const users = await User.find({});
|
|
64
|
+
|
|
65
|
+
// GOOD - Plain JS objects (2-5x faster)
|
|
66
|
+
const users = await User.find({}).lean();
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### 4. Limit Results
|
|
70
|
+
|
|
71
|
+
```typescript
|
|
72
|
+
// BAD - Returns all
|
|
73
|
+
const users = await User.find({ role: 'user' });
|
|
74
|
+
|
|
75
|
+
// GOOD - Paginated
|
|
76
|
+
const users = await User.find({ role: 'user' })
|
|
77
|
+
.skip((page - 1) * limit)
|
|
78
|
+
.limit(limit);
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### 5. Use Cursor for Large Datasets
|
|
82
|
+
|
|
83
|
+
```typescript
|
|
84
|
+
// BAD - Loads all in memory
|
|
85
|
+
const allUsers = await User.find({});
|
|
86
|
+
for (const user of allUsers) {
|
|
87
|
+
/* ... */
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// GOOD - Streams documents
|
|
91
|
+
const cursor = User.find({}).cursor();
|
|
92
|
+
for await (const user of cursor) {
|
|
93
|
+
/* ... */
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### 6. Batch Operations
|
|
98
|
+
|
|
99
|
+
```typescript
|
|
100
|
+
// BAD - Many individual saves
|
|
101
|
+
for (const item of items) {
|
|
102
|
+
await Model.create(item);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// GOOD - Bulk operation
|
|
106
|
+
await Model.insertMany(items);
|
|
107
|
+
|
|
108
|
+
// GOOD - Bulk write for mixed ops
|
|
109
|
+
await Model.bulkWrite([
|
|
110
|
+
{ insertOne: { document: { ... } } },
|
|
111
|
+
{ updateOne: { filter: { ... }, update: { ... } } },
|
|
112
|
+
{ deleteOne: { filter: { ... } } },
|
|
113
|
+
]);
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### 7. Avoid $where and $regex (start)
|
|
117
|
+
|
|
118
|
+
```typescript
|
|
119
|
+
// BAD - Can't use index
|
|
120
|
+
await User.find({ $where: 'this.name.length > 10' });
|
|
121
|
+
await User.find({ name: /^.*john/i }); // Starts with wildcard
|
|
122
|
+
|
|
123
|
+
// GOOD - Use structured queries
|
|
124
|
+
await User.find({ 'name.10': { $exists: true } }); // name longer than 10
|
|
125
|
+
await User.find({ name: /^john/i }); // Starts with john (can use index)
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### 8. Use $in Instead of $or
|
|
129
|
+
|
|
130
|
+
```typescript
|
|
131
|
+
// LESS OPTIMAL
|
|
132
|
+
await User.find({
|
|
133
|
+
$or: [{ status: 'active' }, { status: 'pending' }],
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
// MORE OPTIMAL
|
|
137
|
+
await User.find({ status: { $in: ['active', 'pending'] } });
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
## Query Patterns
|
|
141
|
+
|
|
142
|
+
### Pagination with Count
|
|
143
|
+
|
|
144
|
+
```typescript
|
|
145
|
+
async function paginate(query: object, page: number, limit: number) {
|
|
146
|
+
const [items, total] = await Promise.all([
|
|
147
|
+
Model.find(query)
|
|
148
|
+
.skip((page - 1) * limit)
|
|
149
|
+
.limit(limit)
|
|
150
|
+
.lean(),
|
|
151
|
+
Model.countDocuments(query),
|
|
152
|
+
]);
|
|
153
|
+
|
|
154
|
+
return {
|
|
155
|
+
items,
|
|
156
|
+
total,
|
|
157
|
+
page,
|
|
158
|
+
pages: Math.ceil(total / limit),
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
### Efficient Exists Check
|
|
164
|
+
|
|
165
|
+
```typescript
|
|
166
|
+
// BAD - Fetches document
|
|
167
|
+
const exists = (await User.findOne({ email })) !== null;
|
|
168
|
+
|
|
169
|
+
// GOOD - Only checks existence
|
|
170
|
+
const exists = await User.exists({ email });
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### Selective Population
|
|
174
|
+
|
|
175
|
+
```typescript
|
|
176
|
+
// BAD - Populates everything
|
|
177
|
+
await Order.find({}).populate('user').populate('items.product');
|
|
178
|
+
|
|
179
|
+
// GOOD - Select specific fields
|
|
180
|
+
await Order.find({}).populate('user', 'name email').populate('items.product', 'name price');
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
## Output Format
|
|
184
|
+
|
|
185
|
+
```markdown
|
|
186
|
+
## Query Optimization Report
|
|
187
|
+
|
|
188
|
+
### Original Query
|
|
189
|
+
|
|
190
|
+
\`\`\`typescript
|
|
191
|
+
await User.find({ role: 'admin', isActive: true })
|
|
192
|
+
\`\`\`
|
|
193
|
+
|
|
194
|
+
### Analysis
|
|
195
|
+
|
|
196
|
+
- Execution time: 850ms
|
|
197
|
+
- Stage: COLLSCAN (full table scan!)
|
|
198
|
+
- Docs examined: 50,000
|
|
199
|
+
- Docs returned: 15
|
|
200
|
+
|
|
201
|
+
### Issues
|
|
202
|
+
|
|
203
|
+
1. No index on { role, isActive }
|
|
204
|
+
2. Fetching entire document
|
|
205
|
+
|
|
206
|
+
### Optimized Query
|
|
207
|
+
|
|
208
|
+
\`\`\`typescript
|
|
209
|
+
await User.find({ role: 'admin', isActive: true })
|
|
210
|
+
.select('name email role')
|
|
211
|
+
.lean();
|
|
212
|
+
|
|
213
|
+
// Add index
|
|
214
|
+
UserSchema.index({ role: 1, isActive: 1 });
|
|
215
|
+
\`\`\`
|
|
216
|
+
|
|
217
|
+
### Expected Improvement
|
|
218
|
+
|
|
219
|
+
- Execution time: ~5ms (170x faster)
|
|
220
|
+
- Stage: IXSCAN
|
|
221
|
+
- Docs examined: 15
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
## Critical Rules
|
|
225
|
+
|
|
226
|
+
1. **EXPLAIN FIRST** - Always analyze before optimizing
|
|
227
|
+
2. **INDEX FOR $MATCH** - Common queries need indexes
|
|
228
|
+
3. **SELECT MINIMALLY** - Only fields you need
|
|
229
|
+
4. **USE LEAN** - For read-only operations
|
|
230
|
+
5. **PAGINATE ALWAYS** - Never return unbounded results
|