Skip to content

Commit 79f0814

Browse files
h3n4lclaude
andauthored
feat: add aggregate() operation support (#6) (#6)
Add support for db.collection.aggregate([pipeline]) with comprehensive tests based on MongoDB official documentation examples. Changes: - Add opAggregate operation type and pipeline field - Add extractAggregationPipeline() to parse pipeline from genericMethod - Add executeAggregate() using collection.Aggregate() - Add 8 test functions covering basic stages, $group, $lookup, $unwind Test coverage includes all 5 MongoDB aggregation tutorial examples: - Filtered Subset ($match + $sort + $limit + $unset) - Group and Total ($group with $first/$sum) - Unwind Arrays ($unwind + $match + $group) - One-to-One Join ($lookup simple) - Multi-Field Join ($lookup with let/pipeline/$expr) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 4299ca8 commit 79f0814

3 files changed

Lines changed: 819 additions & 4 deletions

File tree

executor.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ func executeOperation(ctx context.Context, client *mongo.Client, database string
6363
return executeFind(ctx, client, database, op)
6464
case opFindOne:
6565
return executeFindOne(ctx, client, database, op)
66+
case opAggregate:
67+
return executeAggregate(ctx, client, database, op)
6668
case opShowDatabases:
6769
return executeShowDatabases(ctx, client)
6870
case opShowCollections:
@@ -131,6 +133,45 @@ func executeFind(ctx context.Context, client *mongo.Client, database string, op
131133
}, nil
132134
}
133135

136+
// executeAggregate executes an aggregation pipeline.
137+
func executeAggregate(ctx context.Context, client *mongo.Client, database string, op *mongoOperation) (*Result, error) {
138+
collection := client.Database(database).Collection(op.collection)
139+
140+
pipeline := op.pipeline
141+
if pipeline == nil {
142+
pipeline = bson.A{}
143+
}
144+
145+
cursor, err := collection.Aggregate(ctx, pipeline)
146+
if err != nil {
147+
return nil, fmt.Errorf("aggregate failed: %w", err)
148+
}
149+
defer func() { _ = cursor.Close(ctx) }()
150+
151+
var rows []string
152+
for cursor.Next(ctx) {
153+
var doc bson.M
154+
if err := cursor.Decode(&doc); err != nil {
155+
return nil, fmt.Errorf("decode failed: %w", err)
156+
}
157+
158+
jsonBytes, err := bson.MarshalExtJSONIndent(doc, false, false, "", " ")
159+
if err != nil {
160+
return nil, fmt.Errorf("marshal failed: %w", err)
161+
}
162+
rows = append(rows, string(jsonBytes))
163+
}
164+
165+
if err := cursor.Err(); err != nil {
166+
return nil, fmt.Errorf("cursor error: %w", err)
167+
}
168+
169+
return &Result{
170+
Rows: rows,
171+
RowCount: len(rows),
172+
}, nil
173+
}
174+
134175
// executeFindOne executes a findOne operation.
135176
func executeFindOne(ctx context.Context, client *mongo.Client, database string, op *mongoOperation) (*Result, error) {
136177
collection := client.Database(database).Collection(op.collection)

0 commit comments

Comments
 (0)