@@ -183,7 +183,7 @@ export async function deleteMovie(id: string): Promise<{ success: boolean; error
183183 */
184184export async function createMovie ( movieData : Omit < Movie , '_id' > ) : Promise < { success : boolean ; error ?: string ; movieId ?: string } > {
185185 try {
186- const response = await fetch ( `${ API_BASE_URL } /api/movies/ ` , {
186+ const response = await fetch ( `${ API_BASE_URL } /api/movies` , {
187187 method : 'POST' ,
188188 headers : {
189189 'Content-Type' : 'application/json' ,
@@ -276,7 +276,7 @@ export async function deleteMoviesBatch(movieIds: string[]): Promise<{ success:
276276 }
277277 } ;
278278
279- const response = await fetch ( `${ API_BASE_URL } /api/movies/ ` , {
279+ const response = await fetch ( `${ API_BASE_URL } /api/movies` , {
280280 method : 'DELETE' ,
281281 headers : {
282282 'Content-Type' : 'application/json' ,
@@ -326,7 +326,7 @@ export async function updateMoviesBatch(movieIds: string[], updateData: Partial<
326326 }
327327 } ;
328328
329- const response = await fetch ( `${ API_BASE_URL } /api/movies/ ` , {
329+ const response = await fetch ( `${ API_BASE_URL } /api/movies` , {
330330 method : 'PATCH' ,
331331 headers : {
332332 'Content-Type' : 'application/json' ,
@@ -364,80 +364,6 @@ export async function updateMoviesBatch(movieIds: string[], updateData: Partial<
364364 }
365365}
366366
367- /**
368- * Search movies using MongoDB Search across multiple fields with pagination support
369- */
370- export async function searchMovies ( searchParams : {
371- plot ?: string ;
372- fullplot ?: string ;
373- directors ?: string ;
374- writers ?: string ;
375- cast ?: string ;
376- limit ?: number ;
377- skip ?: number ;
378- search_operator ?: 'must' | 'should' | 'mustNot' | 'filter' ;
379- } ) : Promise < { success : boolean ; error ?: string ; movies ?: Movie [ ] ; hasNextPage ?: boolean ; hasPrevPage ?: boolean ; totalCount ?: number } > {
380- try {
381- // Build query parameters
382- const limit = searchParams . limit || 20 ;
383- const skip = searchParams . skip || 0 ;
384-
385- const queryParams = new URLSearchParams ( ) ;
386-
387- if ( searchParams . plot ) queryParams . append ( 'plot' , searchParams . plot ) ;
388- if ( searchParams . fullplot ) queryParams . append ( 'fullplot' , searchParams . fullplot ) ;
389- if ( searchParams . directors ) queryParams . append ( 'directors' , searchParams . directors ) ;
390- if ( searchParams . writers ) queryParams . append ( 'writers' , searchParams . writers ) ;
391- if ( searchParams . cast ) queryParams . append ( 'cast' , searchParams . cast ) ;
392- queryParams . append ( 'limit' , limit . toString ( ) ) ;
393- queryParams . append ( 'skip' , skip . toString ( ) ) ;
394- if ( searchParams . search_operator ) queryParams . append ( 'search_operator' , searchParams . search_operator ) ;
395-
396- const response = await fetch ( `${ API_BASE_URL } /api/movies/search?${ queryParams } ` , {
397- method : 'GET' ,
398- headers : {
399- 'Content-Type' : 'application/json' ,
400- } ,
401- } ) ;
402-
403- const result = await response . json ( ) ;
404-
405- if ( ! response . ok ) {
406- return {
407- success : false ,
408- error : result . message || result . error ?. message || `Failed to search movies: ${ response . status } `
409- } ;
410- }
411-
412- if ( ! result . success ) {
413- return {
414- success : false ,
415- error : result . message || result . error ?. message || 'API returned error response'
416- } ;
417- }
418-
419- const responseData = result . data || { } ;
420- const movies = responseData . movies || [ ] ;
421- const totalCount = responseData . totalCount || 0 ;
422- const hasNextPage = skip + limit < totalCount ;
423- const hasPrevPage = skip > 0 ;
424-
425- return {
426- success : true ,
427- movies,
428- hasNextPage,
429- hasPrevPage,
430- totalCount
431- } ;
432- } catch ( error ) {
433- console . error ( 'Error searching movies:' , error ) ;
434- return {
435- success : false ,
436- error : 'Network error occurred while searching movies'
437- } ;
438- }
439- }
440-
441367/**
442368 * Aggregation API Functions for Aggregations
443369 */
@@ -655,3 +581,156 @@ export async function fetchDirectorStats(limit: number = 20): Promise<{ success:
655581 } ;
656582 }
657583}
584+
585+ /**
586+ * Search movies using MongoDB Search across multiple fields with pagination support
587+ */
588+ export async function searchMovies ( searchParams : {
589+ plot ?: string ;
590+ fullplot ?: string ;
591+ directors ?: string ;
592+ writers ?: string ;
593+ cast ?: string ;
594+ limit ?: number ;
595+ skip ?: number ;
596+ search_operator ?: 'must' | 'should' | 'mustNot' | 'filter' ;
597+ } ) : Promise < { success : boolean ; error ?: string ; movies ?: Movie [ ] ; hasNextPage ?: boolean ; hasPrevPage ?: boolean ; totalCount ?: number } > {
598+ try {
599+ // Build query parameters
600+ const limit = searchParams . limit || 20 ;
601+ const skip = searchParams . skip || 0 ;
602+
603+ const queryParams = new URLSearchParams ( ) ;
604+
605+ if ( searchParams . plot ) queryParams . append ( 'plot' , searchParams . plot ) ;
606+ if ( searchParams . fullplot ) queryParams . append ( 'fullplot' , searchParams . fullplot ) ;
607+ if ( searchParams . directors ) queryParams . append ( 'directors' , searchParams . directors ) ;
608+ if ( searchParams . writers ) queryParams . append ( 'writers' , searchParams . writers ) ;
609+ if ( searchParams . cast ) queryParams . append ( 'cast' , searchParams . cast ) ;
610+ queryParams . append ( 'limit' , limit . toString ( ) ) ;
611+ queryParams . append ( 'skip' , skip . toString ( ) ) ;
612+ if ( searchParams . search_operator ) queryParams . append ( 'search_operator' , searchParams . search_operator ) ;
613+
614+ const response = await fetch ( `${ API_BASE_URL } /api/movies/search?${ queryParams } ` , {
615+ method : 'GET' ,
616+ headers : {
617+ 'Content-Type' : 'application/json' ,
618+ } ,
619+ } ) ;
620+
621+ const result = await response . json ( ) ;
622+
623+ if ( ! response . ok ) {
624+ return {
625+ success : false ,
626+ error : result . message || result . error ?. message || `Failed to search movies: ${ response . status } `
627+ } ;
628+ }
629+
630+ if ( ! result . success ) {
631+ return {
632+ success : false ,
633+ error : result . message || result . error ?. message || 'API returned error response'
634+ } ;
635+ }
636+
637+ const responseData = result . data || { } ;
638+ const movies = responseData . movies || [ ] ;
639+ const totalCount = responseData . totalCount || 0 ;
640+ const hasNextPage = skip + limit < totalCount ;
641+ const hasPrevPage = skip > 0 ;
642+
643+ return {
644+ success : true ,
645+ movies,
646+ hasNextPage,
647+ hasPrevPage,
648+ totalCount
649+ } ;
650+ } catch ( error ) {
651+ console . error ( 'Error searching movies:' , error ) ;
652+ return {
653+ success : false ,
654+ error : 'Network error occurred while searching movies'
655+ } ;
656+ }
657+ }
658+
659+ /**
660+ * Search movies using MongoDB Vector Search to find movies with similar plots
661+ */
662+ export async function vectorSearchMovies ( searchParams : {
663+ q : string ;
664+ limit ?: number ;
665+ } ) : Promise < { success : boolean ; error ?: string ; movies ?: Movie [ ] ; results ?: any [ ] } > {
666+ try {
667+ const limit = searchParams . limit || 10 ;
668+
669+ const queryParams = new URLSearchParams ( ) ;
670+ queryParams . append ( 'q' , searchParams . q ) ;
671+ queryParams . append ( 'limit' , limit . toString ( ) ) ;
672+
673+ const response = await fetch ( `${ API_BASE_URL } /api/movies/vector-search?${ queryParams } ` , {
674+ method : 'GET' ,
675+ headers : {
676+ 'Content-Type' : 'application/json' ,
677+ } ,
678+ } ) ;
679+
680+ const result = await response . json ( ) ;
681+
682+ if ( ! response . ok ) {
683+ return {
684+ success : false ,
685+ error : result . error || `Failed to perform vector search: ${ response . status } `
686+ } ;
687+ }
688+
689+ if ( ! result . success ) {
690+ return {
691+ success : false ,
692+ error : result . error || 'API returned error response'
693+ } ;
694+ }
695+
696+ // Transform VectorSearchResult objects to Movie objects for backend compatibility
697+ const movies : Movie [ ] = ( result . data || [ ] ) . map ( ( item : any ) => {
698+ // Convert VectorSearchResult to Movie format
699+ return {
700+ _id : item . _id || item . id , // Handle both _id (Python) and id (Java) field names
701+ title : item . title || '' ,
702+ plot : item . plot || '' ,
703+ poster : item . poster ,
704+ year : item . year ,
705+ genres : item . genres || [ ] ,
706+ directors : item . directors || [ ] ,
707+ cast : item . cast || [ ] ,
708+ // Add default values for fields not included in VectorSearchResult
709+ fullplot : undefined ,
710+ released : undefined ,
711+ runtime : undefined ,
712+ writers : [ ] ,
713+ countries : [ ] ,
714+ languages : [ ] ,
715+ rated : undefined ,
716+ awards : undefined ,
717+ imdb : undefined ,
718+ tomatoes : undefined ,
719+ metacritic : undefined ,
720+ type : undefined
721+ } as Movie ;
722+ } ) ;
723+
724+ return {
725+ success : true ,
726+ movies,
727+ results : result . data || [ ]
728+ } ;
729+ } catch ( error ) {
730+ console . error ( 'Error performing vector search:' , error ) ;
731+ return {
732+ success : false ,
733+ error : 'Network error occurred while performing vector search'
734+ } ;
735+ }
736+ }
0 commit comments