File tree Expand file tree Collapse file tree 3 files changed +66
-1
lines changed
lib/Doctrine/ODM/MongoDB/Aggregation
tests/Doctrine/ODM/MongoDB/Tests Expand file tree Collapse file tree 3 files changed +66
-1
lines changed Original file line number Diff line number Diff line change @@ -264,6 +264,11 @@ public function getAggregation(array $options = []): IterableResult
264264 * @param bool $applyFilters Whether to apply filters on the aggregation
265265 * pipeline stage
266266 *
267+ * For pipelines where the first stage is a $match stage, it will merge
268+ * the document filters with the existing stage in a logical $and. This is
269+ * required as $text operator can be used anywhere in the first $match stage
270+ * or in the document filters.
271+ *
267272 * For pipelines where the first stage is a $geoNear stage, it will apply
268273 * the document filters and discriminator queries to the query portion of
269274 * the geoNear operation. For all other pipelines, it prepends a $match stage
@@ -314,7 +319,16 @@ public function getPipeline(/* bool $applyFilters = true */): array
314319
315320 $ matchExpression = $ this ->applyFilters ([]);
316321 if ($ matchExpression !== []) {
317- array_unshift ($ pipeline , ['$match ' => $ matchExpression ]);
322+ if (! empty ($ pipeline [0 ]['$match ' ])) {
323+ $ pipeline [0 ]['$match ' ] = [
324+ '$and ' => [
325+ $ matchExpression ,
326+ $ pipeline [0 ]['$match ' ],
327+ ],
328+ ];
329+ } else {
330+ array_unshift ($ pipeline , ['$match ' => $ matchExpression ]);
331+ }
318332 }
319333
320334 return $ pipeline ;
Original file line number Diff line number Diff line change @@ -368,6 +368,39 @@ public function testBuilderAppliesFilterAndDiscriminatorWithMatchStage(): void
368368 self ::assertEquals ($ expectedPipeline , $ builder ->getPipeline ());
369369 }
370370
371+ public function testBuilderMergeFilterAndDiscriminatorWithMatchStage (): void
372+ {
373+ $ this ->dm ->getFilterCollection ()->enable ('testFilter ' );
374+ $ filter = $ this ->dm ->getFilterCollection ()->getFilter ('testFilter ' );
375+ $ filter ->setParameter ('class ' , GuestServer::class);
376+ $ filter ->setParameter ('field ' , 'filtered ' );
377+ $ filter ->setParameter ('value ' , true );
378+
379+ $ builder = $ this ->dm ->createAggregationBuilder (GuestServer::class);
380+ $ builder
381+ ->match ()
382+ ->text ('Paul ' );
383+
384+ $ expectedPipeline = [
385+ [
386+ '$match ' => [
387+ '$and ' => [
388+ [
389+ '$and ' => [
390+ ['stype ' => 'server_guest ' ],
391+ ['filtered ' => true ],
392+ ],
393+ ],
394+ ['$text ' => ['$search ' => 'Paul ' ]],
395+ ],
396+ ],
397+
398+ ],
399+ ];
400+
401+ self ::assertEquals ($ expectedPipeline , $ builder ->getPipeline ());
402+ }
403+
371404 public function testBuilderAppliesFilterAndDiscriminatorWithGeoNearStage (): void
372405 {
373406 $ this ->dm ->getFilterCollection ()->enable ('testFilter ' );
Original file line number Diff line number Diff line change @@ -334,4 +334,22 @@ public function testMultipleFiltersOnSameField(): void
334334 */
335335 self ::assertEmpty ($ this ->getUsernamesWithFindAll ());
336336 }
337+
338+ public function testFilterOnMatchStageUsingTextOperator (): void
339+ {
340+ $ this ->dm ->getDocumentCollection (User::class)->createIndex (['username ' => 'text ' ]);
341+
342+ $ this ->fc ->enable ('testFilter ' );
343+ $ testFilter = $ this ->fc ->getFilter ('testFilter ' );
344+ $ testFilter ->setParameter ('class ' , User::class);
345+ $ testFilter ->setParameter ('field ' , 'hits ' );
346+ $ testFilter ->setParameter ('value ' , 10 );
347+
348+ $ builder = $ this ->dm ->createAggregationBuilder (User::class)
349+ ->match ()
350+ ->field ('username ' )
351+ ->text ('John ' );
352+
353+ self ::assertCount (1 , $ builder ->getAggregation ()->execute ());
354+ }
337355}
You can’t perform that action at this time.
0 commit comments