From 26bb3a1d853a24bb6ccdd6ed624115d2934dc9e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Tamarelle?= Date: Tue, 10 Sep 2024 11:05:09 +0200 Subject: [PATCH 1/4] PHPLIB-1419 Encode Agg builder objects in Collection methods --- src/Collection.php | 30 +- src/Operation/BulkWrite.php | 14 + .../BuilderCollectionFunctionalTest.php | 270 ++++++++++++++++++ 3 files changed, 312 insertions(+), 2 deletions(-) create mode 100644 tests/Collection/BuilderCollectionFunctionalTest.php diff --git a/src/Collection.php b/src/Collection.php index 28133ff55..ba1b7b6b3 100644 --- a/src/Collection.php +++ b/src/Collection.php @@ -23,6 +23,7 @@ use MongoDB\BSON\JavascriptInterface; use MongoDB\BSON\PackedArray; use MongoDB\Builder\BuilderEncoder; +use MongoDB\Builder\Pipeline; use MongoDB\Codec\DocumentCodec; use MongoDB\Codec\Encoder; use MongoDB\Driver\CursorInterface; @@ -221,8 +222,9 @@ public function __toString() * @throws InvalidArgumentException for parameter/option parsing errors * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function aggregate(array $pipeline, array $options = []) + public function aggregate(array|Pipeline $pipeline, array $options = []) { + $pipeline = $this->builderEncoder->encodeIfSupported($pipeline); $hasWriteStage = is_last_pipeline_operator_write($pipeline); $options = $this->inheritReadPreference($options); @@ -262,6 +264,7 @@ public function aggregate(array $pipeline, array $options = []) */ public function bulkWrite(array $operations, array $options = []) { + $options = $this->inheritBuilderEncoder($options); $options = $this->inheritWriteOptions($options); $options = $this->inheritCodec($options); @@ -286,6 +289,7 @@ public function bulkWrite(array $operations, array $options = []) */ public function count(array|object $filter = [], array $options = []) { + $filter = $this->builderEncoder->encodeIfSupported($filter); $options = $this->inheritReadOptions($options); $operation = new Count($this->databaseName, $this->collectionName, $filter, $options); @@ -307,6 +311,7 @@ public function count(array|object $filter = [], array $options = []) */ public function countDocuments(array|object $filter = [], array $options = []) { + $filter = $this->builderEncoder->encodeIfSupported($filter); $options = $this->inheritReadOptions($options); $operation = new CountDocuments($this->databaseName, $this->collectionName, $filter, $options); @@ -444,6 +449,7 @@ public function createSearchIndexes(array $indexes, array $options = []): array */ public function deleteMany(array|object $filter, array $options = []) { + $filter = $this->builderEncoder->encodeIfSupported($filter); $options = $this->inheritWriteOptions($options); $operation = new DeleteMany($this->databaseName, $this->collectionName, $filter, $options); @@ -465,6 +471,7 @@ public function deleteMany(array|object $filter, array $options = []) */ public function deleteOne(array|object $filter, array $options = []) { + $filter = $this->builderEncoder->encodeIfSupported($filter); $options = $this->inheritWriteOptions($options); $operation = new DeleteOne($this->databaseName, $this->collectionName, $filter, $options); @@ -487,6 +494,7 @@ public function deleteOne(array|object $filter, array $options = []) */ public function distinct(string $fieldName, array|object $filter = [], array $options = []) { + $filter = $this->builderEncoder->encodeIfSupported($filter); $options = $this->inheritReadOptions($options); $options = $this->inheritTypeMap($options); @@ -645,6 +653,7 @@ public function explain(Explainable $explainable, array $options = []) */ public function find(array|object $filter = [], array $options = []) { + $filter = $this->builderEncoder->encodeIfSupported($filter); $options = $this->inheritReadOptions($options); $options = $this->inheritCodecOrTypeMap($options); @@ -667,6 +676,7 @@ public function find(array|object $filter = [], array $options = []) */ public function findOne(array|object $filter = [], array $options = []) { + $filter = $this->builderEncoder->encodeIfSupported($filter); $options = $this->inheritReadOptions($options); $options = $this->inheritCodecOrTypeMap($options); @@ -692,6 +702,7 @@ public function findOne(array|object $filter = [], array $options = []) */ public function findOneAndDelete(array|object $filter, array $options = []) { + $filter = $this->builderEncoder->encodeIfSupported($filter); $options = $this->inheritWriteOptions($options); $options = $this->inheritCodecOrTypeMap($options); @@ -722,6 +733,7 @@ public function findOneAndDelete(array|object $filter, array $options = []) */ public function findOneAndReplace(array|object $filter, array|object $replacement, array $options = []) { + $filter = $this->builderEncoder->encodeIfSupported($filter); $options = $this->inheritWriteOptions($options); $options = $this->inheritCodecOrTypeMap($options); @@ -752,6 +764,7 @@ public function findOneAndReplace(array|object $filter, array|object $replacemen */ public function findOneAndUpdate(array|object $filter, array|object $update, array $options = []) { + $filter = $this->builderEncoder->encodeIfSupported($filter); $options = $this->inheritWriteOptions($options); $options = $this->inheritCodecOrTypeMap($options); @@ -1000,6 +1013,7 @@ public function rename(string $toCollectionName, ?string $toDatabaseName = null, */ public function replaceOne(array|object $filter, array|object $replacement, array $options = []) { + $filter = $this->builderEncoder->encodeIfSupported($filter); $options = $this->inheritWriteOptions($options); $options = $this->inheritCodec($options); @@ -1023,6 +1037,8 @@ public function replaceOne(array|object $filter, array|object $replacement, arra */ public function updateMany(array|object $filter, array|object $update, array $options = []) { + $filter = $this->builderEncoder->encodeIfSupported($filter); + $update = $this->builderEncoder->encodeIfSupported($update); $options = $this->inheritWriteOptions($options); $operation = new UpdateMany($this->databaseName, $this->collectionName, $filter, $update, $options); @@ -1045,6 +1061,8 @@ public function updateMany(array|object $filter, array|object $update, array $op */ public function updateOne(array|object $filter, array|object $update, array $options = []) { + $filter = $this->builderEncoder->encodeIfSupported($filter); + $update = $this->builderEncoder->encodeIfSupported($update); $options = $this->inheritWriteOptions($options); $operation = new UpdateOne($this->databaseName, $this->collectionName, $filter, $update, $options); @@ -1080,8 +1098,9 @@ public function updateSearchIndex(string $name, array|object $definition, array * @return ChangeStream * @throws InvalidArgumentException for parameter/option parsing errors */ - public function watch(array $pipeline = [], array $options = []) + public function watch(array|Pipeline $pipeline = [], array $options = []) { + $pipeline = $this->builderEncoder->encodeIfSupported($pipeline); $options = $this->inheritReadOptions($options); $options = $this->inheritCodecOrTypeMap($options); @@ -1112,6 +1131,13 @@ public function withOptions(array $options = []) return new Collection($this->manager, $this->databaseName, $this->collectionName, $options); } + private function inheritBuilderEncoder(array $options): array + { + $options['builderEncoder'] = $this->builderEncoder; + + return $options; + } + private function inheritCodec(array $options): array { // If the options contain a type map, don't inherit anything diff --git a/src/Operation/BulkWrite.php b/src/Operation/BulkWrite.php index 700ce3943..f75ba5d59 100644 --- a/src/Operation/BulkWrite.php +++ b/src/Operation/BulkWrite.php @@ -17,8 +17,10 @@ namespace MongoDB\Operation; +use MongoDB\Builder\BuilderEncoder; use MongoDB\BulkWriteResult; use MongoDB\Codec\DocumentCodec; +use MongoDB\Codec\Encoder; use MongoDB\Driver\BulkWrite as Bulk; use MongoDB\Driver\Exception\RuntimeException as DriverRuntimeException; use MongoDB\Driver\Server; @@ -94,6 +96,9 @@ class BulkWrite implements Executable * * Supported options for the bulk write operation: * + * * builderEncoder (MongoDB\Builder\Encoder): Encoder for query and + * aggregation builders. If not given, the default encoder will be used. + * * * bypassDocumentValidation (boolean): If true, allows the write to * circumvent document level validation. The default is false. * @@ -137,6 +142,10 @@ public function __construct(private string $databaseName, private string $collec $options += ['ordered' => true]; + if (isset($options['builderEncoder']) && ! $options['builderEncoder'] instanceof Encoder) { + throw InvalidArgumentException::invalidType('"builderEncoder" option', $options['builderEncoder'], Encoder::class); + } + if (isset($options['bypassDocumentValidation']) && ! is_bool($options['bypassDocumentValidation'])) { throw InvalidArgumentException::invalidType('"bypassDocumentValidation" option', $options['bypassDocumentValidation'], 'boolean'); } @@ -188,6 +197,8 @@ public function execute(Server $server) throw UnsupportedException::writeConcernNotSupportedInTransaction(); } + $builderEncoder = $operation['builderEncoder'] ?? new BuilderEncoder(); + $bulk = new Bulk($this->createBulkWriteOptions()); $insertedIds = []; @@ -198,6 +209,7 @@ public function execute(Server $server) switch ($type) { case self::DELETE_MANY: case self::DELETE_ONE: + $args[0] = $builderEncoder->encodeIfSupported($args[0]); $bulk->delete($args[0], $args[1]); break; @@ -208,6 +220,8 @@ public function execute(Server $server) case self::UPDATE_MANY: case self::UPDATE_ONE: case self::REPLACE_ONE: + $args[0] = $builderEncoder->encodeIfSupported($args[0]); + $args[1] = $builderEncoder->encodeIfSupported($args[1]); $bulk->update($args[0], $args[1], $args[2]); break; } diff --git a/tests/Collection/BuilderCollectionFunctionalTest.php b/tests/Collection/BuilderCollectionFunctionalTest.php new file mode 100644 index 000000000..a36d77021 --- /dev/null +++ b/tests/Collection/BuilderCollectionFunctionalTest.php @@ -0,0 +1,270 @@ +collection->insertMany([['x' => 1], ['x' => 2], ['x' => 2]]); + } + + public function testAggregate(): void + { + $this->collection->insertMany([['x' => 10], ['x' => 10], ['x' => 10]]); + $pipeline = new Pipeline( + Stage::bucketAuto( + groupBy: Expression::intFieldPath('x'), + buckets: 2, + ), + ); + $results = $this->collection->aggregate($pipeline)->toArray(); + $this->assertCount(2, $results); + } + + public function testBulkWriteDeleteMany(): void + { + $result = $this->collection->bulkWrite([ + [ + 'deleteMany' => [ + Query::query(x: Query::gt(1)), + ], + ], + ]); + $this->assertEquals(2, $result->getDeletedCount()); + } + + public function testBulkWriteDeleteOne(): void + { + $result = $this->collection->bulkWrite([ + [ + 'deleteOne' => [ + Query::query(x: Query::eq(1)), + ], + ], + ]); + $this->assertEquals(1, $result->getDeletedCount()); + } + + public function testBulkWriteReplaceOne(): void + { + $result = $this->collection->bulkWrite([ + [ + 'replaceOne' => [ + Query::query(x: Query::eq(1)), + ['x' => 3], + ], + ], + ]); + $this->assertEquals(1, $result->getModifiedCount()); + + $result = $this->collection->findOne(Query::query(x: Query::eq(3))); + $this->assertEquals(3, $result->x); + } + + public function testBulkWriteUpdateMany(): void + { + $result = $this->collection->bulkWrite([ + [ + 'updateMany' => [ + Query::query(x: Query::gt(1)), + // @todo Use Builder when update operators are supported by PHPLIB-1507 + ['$set' => ['x' => 3]], + ], + ], + ]); + $this->assertEquals(2, $result->getModifiedCount()); + + $result = $this->collection->find(Query::query(x: Query::eq(3)))->toArray(); + $this->assertCount(2, $result); + $this->assertEquals(3, $result[0]->x); + } + + public function testBulkWriteUpdateOne(): void + { + $result = $this->collection->bulkWrite([ + [ + 'updateOne' => [ + Query::query(x: Query::eq(1)), + // @todo Use Builder when update operators are supported by PHPLIB-1507 + ['$set' => ['x' => 3]], + ], + ], + ]); + + $this->assertEquals(1, $result->getModifiedCount()); + + $result = $this->collection->findOne(Query::query(x: Query::eq(3))); + $this->assertEquals(3, $result->x); + } + + public function testCountDocuments(): void + { + $result = $this->collection->countDocuments(Query::query(x: Query::gt(1))); + $this->assertEquals(2, $result); + } + + public function testDeleteMany(): void + { + $result = $this->collection->deleteMany(Query::query(x: Query::gt(1))); + $this->assertEquals(2, $result->getDeletedCount()); + } + + public function testDeleteOne(): void + { + $result = $this->collection->deleteOne(Query::query(x: Query::gt(1))); + $this->assertEquals(1, $result->getDeletedCount()); + } + + public function testDistinct(): void + { + $result = $this->collection->distinct('x', Query::query(x: Query::gt(1))); + $this->assertEquals([2], $result); + } + + public function testFind(): void + { + $results = $this->collection->find(Query::query(x: Query::gt(1)))->toArray(); + $this->assertCount(2, $results); + $this->assertEquals(2, $results[0]->x); + } + + public function testFindOne(): void + { + $result = $this->collection->findOne(Query::query(x: Query::eq(1))); + $this->assertEquals(1, $result->x); + } + + public function testFindOneAndDelete(): void + { + $result = $this->collection->findOneAndDelete(Query::query(x: Query::eq(1))); + $this->assertEquals(1, $result->x); + + $result = $this->collection->find()->toArray(); + $this->assertCount(2, $result); + } + + public function testFindOneAndReplace(): void + { + $this->collection->insertOne(['x' => 1]); + + $result = $this->collection->findOneAndReplace( + Query::query(x: Query::lt(2)), + ['x' => 3], + ); + $this->assertEquals(1, $result->x); + + $result = $this->collection->findOne(Query::query(x: Query::eq(3))); + $this->assertEquals(3, $result->x); + } + + public function testFindOneAndUpdate(): void + { + $result = $this->collection->findOneAndUpdate( + Query::query(x: Query::lt(2)), + // @todo Use Builder when update operators are supported by PHPLIB-1507 + ['$set' => ['x' => 3]], + ); + $this->assertEquals(1, $result->x); + + $result = $this->collection->findOne(Query::query(x: Query::eq(3))); + $this->assertEquals(3, $result->x); + } + + public function testReplaceOne(): void + { + $this->collection->insertOne(['x' => 1]); + + $result = $this->collection->replaceOne( + Query::query(x: Query::lt(2)), + ['x' => 3], + ); + $this->assertEquals(1, $result->getModifiedCount()); + + $result = $this->collection->findOne(Query::query(x: Query::eq(3))); + $this->assertEquals(3, $result->x); + } + + public function testUpdateOne(): void + { + $this->collection->insertOne(['x' => 1]); + + $result = $this->collection->updateOne( + Query::query(x: Query::lt(2)), + // @todo Use Builder when update operators are supported by PHPLIB-1507 + ['$set' => ['x' => 3]], + ); + $this->assertEquals(1, $result->getModifiedCount()); + + $result = $this->collection->findOne(Query::query(x: Query::eq(3))); + $this->assertEquals(3, $result->x); + } + + public function testUpdateWithPipeline(): void + { + $result = $this->collection->updateOne( + Query::query(x: Query::lt(2)), + new Pipeline( + Stage::set(x: 3), + ), + ); + + $this->assertEquals(1, $result->getModifiedCount()); + } + + public function testUpdateMany(): void + { + $result = $this->collection->updateMany( + Query::query(x: Query::gt(1)), + // @todo Use Builder when update operators are supported by PHPLIB-1507 + ['$set' => ['x' => 3]], + ); + $this->assertEquals(2, $result->getModifiedCount()); + + $result = $this->collection->find(Query::query(x: Query::eq(3)))->toArray(); + $this->assertCount(2, $result); + $this->assertEquals(3, $result[0]->x); + } + + public function testUpdateManyWithPipeline(): void + { + $result = $this->collection->updateMany( + Query::query(x: Query::gt(1)), + new Pipeline( + Stage::set(x: 3), + ), + ); + $this->assertEquals(2, $result->getModifiedCount()); + + $result = $this->collection->find(Query::query(x: Query::eq(3)))->toArray(); + $this->assertCount(2, $result); + $this->assertEquals(3, $result[0]->x); + } + + public function testWatch(): void + { + $this->skipIfChangeStreamIsNotSupported(); + + if ($this->isShardedCluster()) { + $this->markTestSkipped('Test does not apply on sharded clusters: need more than a single getMore call on the change stream.'); + } + + $pipeline = new Pipeline( + Stage::match(operationType: Query::eq('insert')), + ); + $changeStream = $this->collection->watch($pipeline); + $changeStream->rewind(); + $this->assertNull($changeStream->current()); + $this->collection->insertOne(['x' => 3]); + $changeStream->next(); + $this->assertTrue($changeStream->valid()); + $this->assertEquals('insert', $changeStream->current()->operationType); + } +} From 5949533487912ca18dafcfe144a76775afd88341 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Tamarelle?= Date: Tue, 10 Sep 2024 21:57:24 +0200 Subject: [PATCH 2/4] Ignore static analysis issues --- psalm-baseline.xml | 20 ++++++++++++++++++-- src/Operation/BulkWrite.php | 17 ++++++++++------- 2 files changed, 28 insertions(+), 9 deletions(-) diff --git a/psalm-baseline.xml b/psalm-baseline.xml index 00c11f728..1d8ee73f0 100644 --- a/psalm-baseline.xml +++ b/psalm-baseline.xml @@ -223,6 +223,11 @@ + + + + + @@ -417,8 +422,9 @@ - - + + + @@ -448,6 +454,7 @@ + @@ -458,6 +465,10 @@ + + + + @@ -466,9 +477,14 @@ + + + + + diff --git a/src/Operation/BulkWrite.php b/src/Operation/BulkWrite.php index f75ba5d59..6da8a68b3 100644 --- a/src/Operation/BulkWrite.php +++ b/src/Operation/BulkWrite.php @@ -178,7 +178,7 @@ public function __construct(private string $databaseName, private string $collec unset($options['writeConcern']); } - $this->operations = $this->validateOperations($operations, $options['codec'] ?? null); + $this->operations = $this->validateOperations($operations, $options['codec'] ?? null, $options['builderEncoder'] ?? new BuilderEncoder()); $this->options = $options; } @@ -197,8 +197,6 @@ public function execute(Server $server) throw UnsupportedException::writeConcernNotSupportedInTransaction(); } - $builderEncoder = $operation['builderEncoder'] ?? new BuilderEncoder(); - $bulk = new Bulk($this->createBulkWriteOptions()); $insertedIds = []; @@ -209,7 +207,6 @@ public function execute(Server $server) switch ($type) { case self::DELETE_MANY: case self::DELETE_ONE: - $args[0] = $builderEncoder->encodeIfSupported($args[0]); $bulk->delete($args[0], $args[1]); break; @@ -220,8 +217,6 @@ public function execute(Server $server) case self::UPDATE_MANY: case self::UPDATE_ONE: case self::REPLACE_ONE: - $args[0] = $builderEncoder->encodeIfSupported($args[0]); - $args[1] = $builderEncoder->encodeIfSupported($args[1]); $bulk->update($args[0], $args[1], $args[2]); break; } @@ -278,7 +273,7 @@ private function createExecuteOptions(): array * @param array[] $operations * @return array[] */ - private function validateOperations(array $operations, ?DocumentCodec $codec): array + private function validateOperations(array $operations, ?DocumentCodec $codec, Encoder $builderEncoder): array { foreach ($operations as $i => $operation) { if (! is_array($operation)) { @@ -312,6 +307,8 @@ private function validateOperations(array $operations, ?DocumentCodec $codec): a case self::DELETE_MANY: case self::DELETE_ONE: + $operations[$i][$type][0] = $builderEncoder->encodeIfSupported($args[0]); + if (! isset($args[1])) { $args[1] = []; } @@ -331,6 +328,8 @@ private function validateOperations(array $operations, ?DocumentCodec $codec): a break; case self::REPLACE_ONE: + $operations[$i][$type][0] = $builderEncoder->encodeIfSupported($args[0]); + if (! isset($args[1]) && ! array_key_exists(1, $args)) { throw new InvalidArgumentException(sprintf('Missing second argument for $operations[%d]["%s"]', $i, $type)); } @@ -381,10 +380,14 @@ private function validateOperations(array $operations, ?DocumentCodec $codec): a case self::UPDATE_MANY: case self::UPDATE_ONE: + $operations[$i][$type][0] = $builderEncoder->encodeIfSupported($args[0]); + if (! isset($args[1]) && ! array_key_exists(1, $args)) { throw new InvalidArgumentException(sprintf('Missing second argument for $operations[%d]["%s"]', $i, $type)); } + $operations[$i][$type][1] = $args[1] = $builderEncoder->encodeIfSupported($args[1]); + if ((! is_document($args[1]) || ! is_first_key_operator($args[1])) && ! is_pipeline($args[1])) { throw new InvalidArgumentException(sprintf('Expected update operator(s) or non-empty pipeline for $operations[%d]["%s"][1]', $i, $type)); } From acc21d4a9267f99bb30277ea75a0548f9096f2f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Tamarelle?= Date: Wed, 11 Sep 2024 10:11:54 +0200 Subject: [PATCH 3/4] Skip pipeline in update operations for server version < 4.0 --- src/Collection.php | 4 +--- tests/Collection/BuilderCollectionFunctionalTest.php | 4 ++++ 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/Collection.php b/src/Collection.php index ba1b7b6b3..0b7760f14 100644 --- a/src/Collection.php +++ b/src/Collection.php @@ -1133,9 +1133,7 @@ public function withOptions(array $options = []) private function inheritBuilderEncoder(array $options): array { - $options['builderEncoder'] = $this->builderEncoder; - - return $options; + return ['builderEncoder' => $this->builderEncoder] + $options; } private function inheritCodec(array $options): array diff --git a/tests/Collection/BuilderCollectionFunctionalTest.php b/tests/Collection/BuilderCollectionFunctionalTest.php index a36d77021..14a054075 100644 --- a/tests/Collection/BuilderCollectionFunctionalTest.php +++ b/tests/Collection/BuilderCollectionFunctionalTest.php @@ -209,6 +209,8 @@ public function testUpdateOne(): void public function testUpdateWithPipeline(): void { + $this->skipIfServerVersion('<', '4.2.0', 'Pipeline-style updates are not supported'); + $result = $this->collection->updateOne( Query::query(x: Query::lt(2)), new Pipeline( @@ -235,6 +237,8 @@ public function testUpdateMany(): void public function testUpdateManyWithPipeline(): void { + $this->skipIfServerVersion('<', '4.2.0', 'Pipeline-style updates are not supported'); + $result = $this->collection->updateMany( Query::query(x: Query::gt(1)), new Pipeline( From ba9f715c4181a279af5277fd6bb64d1e7291a35a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Tamarelle?= Date: Wed, 11 Sep 2024 10:32:14 +0200 Subject: [PATCH 4/4] Revert BC break on Collection::aggregate and watch --- psalm-baseline.xml | 5 ---- src/Collection.php | 7 ++--- .../BuilderCollectionFunctionalTest.php | 28 ++----------------- 3 files changed, 4 insertions(+), 36 deletions(-) diff --git a/psalm-baseline.xml b/psalm-baseline.xml index 1d8ee73f0..f51206d0d 100644 --- a/psalm-baseline.xml +++ b/psalm-baseline.xml @@ -223,11 +223,6 @@ - - - - - diff --git a/src/Collection.php b/src/Collection.php index 0b7760f14..7769b9a5b 100644 --- a/src/Collection.php +++ b/src/Collection.php @@ -23,7 +23,6 @@ use MongoDB\BSON\JavascriptInterface; use MongoDB\BSON\PackedArray; use MongoDB\Builder\BuilderEncoder; -use MongoDB\Builder\Pipeline; use MongoDB\Codec\DocumentCodec; use MongoDB\Codec\Encoder; use MongoDB\Driver\CursorInterface; @@ -222,9 +221,8 @@ public function __toString() * @throws InvalidArgumentException for parameter/option parsing errors * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function aggregate(array|Pipeline $pipeline, array $options = []) + public function aggregate(array $pipeline, array $options = []) { - $pipeline = $this->builderEncoder->encodeIfSupported($pipeline); $hasWriteStage = is_last_pipeline_operator_write($pipeline); $options = $this->inheritReadPreference($options); @@ -1098,9 +1096,8 @@ public function updateSearchIndex(string $name, array|object $definition, array * @return ChangeStream * @throws InvalidArgumentException for parameter/option parsing errors */ - public function watch(array|Pipeline $pipeline = [], array $options = []) + public function watch(array $pipeline = [], array $options = []) { - $pipeline = $this->builderEncoder->encodeIfSupported($pipeline); $options = $this->inheritReadOptions($options); $options = $this->inheritCodecOrTypeMap($options); diff --git a/tests/Collection/BuilderCollectionFunctionalTest.php b/tests/Collection/BuilderCollectionFunctionalTest.php index 14a054075..15a89cda5 100644 --- a/tests/Collection/BuilderCollectionFunctionalTest.php +++ b/tests/Collection/BuilderCollectionFunctionalTest.php @@ -2,7 +2,6 @@ namespace MongoDB\Tests\Collection; -use MongoDB\Builder\Expression; use MongoDB\Builder\Pipeline; use MongoDB\Builder\Query; use MongoDB\Builder\Stage; @@ -18,15 +17,7 @@ public function setUp(): void public function testAggregate(): void { - $this->collection->insertMany([['x' => 10], ['x' => 10], ['x' => 10]]); - $pipeline = new Pipeline( - Stage::bucketAuto( - groupBy: Expression::intFieldPath('x'), - buckets: 2, - ), - ); - $results = $this->collection->aggregate($pipeline)->toArray(); - $this->assertCount(2, $results); + $this->markTestSkipped('Not supported yet'); } public function testBulkWriteDeleteMany(): void @@ -254,21 +245,6 @@ public function testUpdateManyWithPipeline(): void public function testWatch(): void { - $this->skipIfChangeStreamIsNotSupported(); - - if ($this->isShardedCluster()) { - $this->markTestSkipped('Test does not apply on sharded clusters: need more than a single getMore call on the change stream.'); - } - - $pipeline = new Pipeline( - Stage::match(operationType: Query::eq('insert')), - ); - $changeStream = $this->collection->watch($pipeline); - $changeStream->rewind(); - $this->assertNull($changeStream->current()); - $this->collection->insertOne(['x' => 3]); - $changeStream->next(); - $this->assertTrue($changeStream->valid()); - $this->assertEquals('insert', $changeStream->current()->operationType); + $this->markTestSkipped('Not supported yet'); } }