diff --git a/src/Database/Adapter/Mongo.php b/src/Database/Adapter/Mongo.php index dcb920144..82a5c7432 100644 --- a/src/Database/Adapter/Mongo.php +++ b/src/Database/Adapter/Mongo.php @@ -41,6 +41,11 @@ class Mongo extends Adapter protected Client $client; + /** + * Default batch size for cursor operations + */ + private const DEFAULT_BATCH_SIZE = 1000; + //protected ?int $timeout = null; /** @@ -1277,15 +1282,43 @@ public function getSequences(string $collection, array $documents): array $filters['_tenant'] = $this->getTenantFilters($collection, $documentTenants); } try { - $results = $this->client->find($name, $filters, ['projection' => ['_uid' => 1, '_id' => 1]]); + // Use cursor paging for large result sets + $options = [ + 'projection' => ['_uid' => 1, '_id' => 1], + 'batchSize' => self::DEFAULT_BATCH_SIZE + ]; + + $response = $this->client->find($name, $filters, $options); + $results = $response->cursor->firstBatch ?? []; + + // Process first batch + foreach ($results as $result) { + $sequences[$result->_uid] = (string)$result->_id; + } + + // Get cursor ID for subsequent batches + $cursorId = $response->cursor->id ?? null; + + // Continue fetching with getMore + while ($cursorId && $cursorId !== 0) { + $moreResponse = $this->client->getMore($cursorId, $name, self::DEFAULT_BATCH_SIZE); + $moreResults = $moreResponse->cursor->nextBatch ?? []; + + if (empty($moreResults)) { + break; + } + + foreach ($moreResults as $result) { + $sequences[$result->_uid] = (string)$result->_id; + } + + // Update cursor ID for next iteration + $cursorId = $moreResponse->cursor->id ?? null; + } } catch (MongoException $e) { throw $this->processException($e); } - foreach ($results->cursor->firstBatch as $result) { - $sequences[$result->_uid] = (string)$result->_id; - } - foreach ($documents as $document) { if (isset($sequences[$document->getId()])) { $document['$sequence'] = $sequences[$document->getId()]; @@ -1575,8 +1608,7 @@ public function find(Document $collection, array $queries = [], ?int $limit = 25 try { // Use proper cursor iteration with reasonable batch size - $batchSize = 1000; - $options['batchSize'] = $batchSize; + $options['batchSize'] = self::DEFAULT_BATCH_SIZE; $response = $this->client->find($name, $filters, $options); $results = $response->cursor->firstBatch ?? []; @@ -1597,7 +1629,7 @@ public function find(Document $collection, array $queries = [], ?int $limit = 25 break; } - $moreResponse = $this->client->getMore($cursorId, $name, $batchSize); + $moreResponse = $this->client->getMore($cursorId, $name, self::DEFAULT_BATCH_SIZE); $moreResults = $moreResponse->cursor->nextBatch ?? []; if (empty($moreResults)) {