@@ -3,6 +3,9 @@ import { DbOperationArgs, DbOperationType, MongoDBToolBase } from "../mongodbToo
33import { ToolArgs } from "../../tool.js" ;
44import { z } from "zod" ;
55import { ExplainVerbosity , Document } from "mongodb" ;
6+ import { AggregateArgs } from "../read/aggregate.js" ;
7+ import { FindArgs } from "../read/find.js" ;
8+ import { CountArgs } from "../read/count.js" ;
69
710export class ExplainTool extends MongoDBToolBase {
811 protected name = "explain" ;
@@ -11,42 +14,65 @@ export class ExplainTool extends MongoDBToolBase {
1114
1215 protected argsShape = {
1316 ...DbOperationArgs ,
14- method : z . enum ( [ "aggregate" , "find" ] ) . describe ( "The method to run" ) ,
15- methodArguments : z
16- . object ( {
17- aggregatePipeline : z
18- . array ( z . object ( { } ) . passthrough ( ) )
19- . optional ( )
20- . describe ( "aggregate - array of aggregation stages to execute" ) ,
21-
22- findQuery : z . object ( { } ) . passthrough ( ) . optional ( ) . describe ( "find - The query to run" ) ,
23- findProjection : z . object ( { } ) . passthrough ( ) . optional ( ) . describe ( "find - The projection to apply" ) ,
24- } )
25- . describe ( "The arguments for the method" ) ,
17+ method : z
18+ . array (
19+ z . union ( [
20+ z . object ( {
21+ name : z . literal ( "aggregate" ) ,
22+ arguments : z . object ( AggregateArgs ) ,
23+ } ) ,
24+ z . object ( {
25+ name : z . literal ( "find" ) ,
26+ arguments : z . object ( FindArgs ) ,
27+ } ) ,
28+ z . object ( {
29+ name : z . literal ( "count" ) ,
30+ arguments : z . object ( CountArgs ) ,
31+ } ) ,
32+ ] )
33+ )
34+ . describe ( "The method and its arguments to run" ) ,
2635 } ;
2736
2837 protected operationType : DbOperationType = "metadata" ;
2938
39+ static readonly defaultVerbosity = ExplainVerbosity . queryPlanner ;
40+
3041 protected async execute ( {
3142 database,
3243 collection,
33- method,
34- methodArguments,
44+ method : methods ,
3545 } : ToolArgs < typeof this . argsShape > ) : Promise < CallToolResult > {
3646 const provider = this . ensureConnected ( ) ;
47+ const method = methods [ 0 ] ;
48+
49+ if ( ! method ) {
50+ throw new Error ( "No method provided" ) ;
51+ }
3752
3853 let result : Document ;
39- switch ( method ) {
54+ switch ( method . name ) {
4055 case "aggregate" : {
41- result = await provider . aggregate ( database , collection ) . explain ( ) ;
56+ const { pipeline, limit } = method . arguments ;
57+ result = await provider
58+ . aggregate ( database , collection , pipeline )
59+ . limit ( limit )
60+ . explain ( ExplainTool . defaultVerbosity ) ;
4261 break ;
4362 }
4463 case "find" : {
45- const query = methodArguments . findQuery ?? { } ;
46- const projection = methodArguments . findProjection ?? { } ;
64+ const { filter, ...rest } = method . arguments ;
4765 result = await provider
48- . find ( database , collection , query , { projection } )
49- . explain ( ExplainVerbosity . queryPlanner ) ;
66+ . find ( database , collection , filter , { ...rest } )
67+ . explain ( ExplainTool . defaultVerbosity ) ;
68+ break ;
69+ }
70+ case "count" : {
71+ const { query } = method . arguments ;
72+ // This helper doesn't have explain() command but does have the argument explain
73+ result = ( await provider . count ( database , collection , query , {
74+ explain : ExplainTool . defaultVerbosity ,
75+ } ) ) as unknown as Document ;
5076 break ;
5177 }
5278 default :
0 commit comments