4242use function is_iterable ;
4343use function is_string ;
4444use function iterator_to_array ;
45+ use function method_exists ;
4546use function preg_quote ;
4647use function sleep ;
4748use function sprintf ;
@@ -188,20 +189,33 @@ protected function performSearch(Builder $builder, ?int $offset = null): array
188189 return $ result instanceof CursorInterface ? $ result ->toArray () : $ result ;
189190 }
190191
191- $ compound = [];
192- 193- // Query String
192+ $ compound = [
193+ 'must ' => [
194+ [
195+ 'text ' => [
196+ 'query ' => $ builder ->query ,
197+ 'path ' => ['wildcard ' => '* ' ],
198+ 'fuzzy ' => ['maxEdits ' => 2 ],
199+ ],
200+ ],
201+ ],
202+ ];
194203
195204 foreach ($ builder ->wheres as $ field => $ value ) {
196- $ compound ['filter ' ]['equals ' ][] = ['path ' => $ field , 'value ' => $ value ];
205+ $ compound ['filter ' ][] = [ 'equals ' => ['path ' => $ field , 'value ' => $ value] ];
197206 }
198207
199208 foreach ($ builder ->whereIns as $ field => $ value ) {
200- $ compound ['filter ' ]['in ' ][] = ['path ' => $ field , 'value ' => $ value ];
209+ $ compound ['filter ' ][] = [ 'in ' => ['path ' => $ field , 'value ' => $ value] ];
201210 }
202211
203212 foreach ($ builder ->whereNotIns as $ field => $ value ) {
204- $ compound ['mustNot ' ]['in ' ][] = ['path ' => $ field , 'value ' => $ value ];
213+ $ compound ['mustNot ' ][] = ['in ' => ['path ' => $ field , 'value ' => $ value ]];
214+ }
215+ 216+ $ sort = [];
217+ foreach ($ builder ->orders as $ order ) {
218+ $ sort [$ order ['column ' ]] = $ order ['direction ' ] === 'asc ' ? 1 : -1 ;
205219 }
206220
207221 $ pipeline = [
@@ -210,7 +224,7 @@ protected function performSearch(Builder $builder, ?int $offset = null): array
210224 'index ' => self ::INDEX_NAME ,
211225 'compound ' => $ compound ,
212226 'count ' => ['type ' => 'lowerBound ' ],
213- ' sort ' => array_merge ( ...array_map ( fn ( $ order ) => [ $ order [ ' column ' ] => $ order [ ' direction ' ] === ' asc ' ? 1 : - 1 ], $ builder -> orders ) ),
227+ ...( $ builder -> orders ? [ ' sort ' => $ sort ] : [] ),
214228 ],
215229 ],
216230 [
@@ -236,27 +250,6 @@ protected function performSearch(Builder $builder, ?int $offset = null): array
236250 return $ collection ->aggregate ($ pipeline , $ options )->toArray ();
237251 }
238252
239- /**
240- * Get the filter array for the query.
241- *
242- * @return string
243- */
244- protected function filters (Builder $ builder ): array
245- {
246- $ filters = $ builder ->wheres ;
247- 248- // https://www.mongodb.com/docs/atlas/atlas-search/in/
249- foreach ($ builder ->whereIns as $ field => $ values ) {
250- $ filters ['in ' ][] = ['path ' => $ field , 'value ' => $ values ];
251- }
252- 253- foreach ($ builder ->whereNotIns as $ field => $ values ) {
254- $ filters ['in ' ][] = ['path ' => $ field , 'value ' => $ values ];
255- }
256- 257- return $ filters ;
258- }
259- 260253 /**
261254 * Pluck and return the primary keys of the given results.
262255 *
@@ -494,6 +487,26 @@ private function performSearchIndexOperation(Closure $closure): void
494487 }
495488 }
496489
490+ private function getMapping (Model $ model ): array
491+ {
492+ $ mapping = self ::DEFAULT_DEFINITION ;
493+ 494+ if (method_exists ($ model , 'searchableMapping ' )) {
495+ $ mapping = $ model ->searchableMapping ();
496+ }
497+ 498+ if ($ this ->usesSoftDelete ($ model )) {
499+ // This field is a boolean represented with the integers 0 and 1
500+ $ mapping ['fields ' ]['__soft_deleted ' ] ??= [
501+ 'type ' => 'number ' ,
502+ 'representation ' => 'int64 ' ,
503+ 'indexDoubles ' => false ,
504+ ];
505+ }
506+ 507+ return $ mapping ;
508+ }
509+ 497510 /**
498511 * Wait for the callback to return true, use it for asynchronous
499512 * Atlas Search index management operations.
0 commit comments