Exploring MongoDB's find() in PHP: toArray() vs foreach
Adam C. |

MongoDB's find() method is a powerful way to query multiple documents in PHP. However, the way you process the results can significantly impact the efficiency and readability of your code. This blog post explores two common approaches to handling the results of find() in PHP: using toArray() and iterating directly with foreach.

Photo by Daniele Levis Pelusi on Unsplash

The Basics: find()

The find() method in MongoDB returns a cursor, which is an iterable object that allows you to traverse through documents one by one. You can process the documents directly or convert the cursor into an array for batch processing.

Example Query

$cursor = $collection->find([
    'teamCode' => 'RMSC',
]);

This retrieves all documents where teamCode is 'RMSC'.

Now, let's explore the two methods of processing these results.

Method 1: Using toArray()

The toArray() method converts the entire cursor into a PHP array. This is useful when you need all documents at once, such as passing them to a function or performing batch operations.

Example

$documents = $cursor->toArray(); // Converts the cursor into an array

foreach ($documents as $doc) {
    echo "Slug: " . $doc['slug'] . "\n";
}

// The documents array is reusable
print_r($documents);

Pros

  • Convenience: All documents are immediately available as an array.
  • Reusability: The resulting array can be passed to functions or processed multiple times.

Cons

  • Memory Usage: Loads all documents into memory at once, which can be problematic for large datasets.
  • Batch Processing Only: You lose the ability to process documents incrementally.

Method 2: Using foreach Directly on the Cursor

Instead of converting the cursor, you can iterate over it directly using foreach. This streams documents one at a time from MongoDB, which is more memory-efficient for large datasets.

Example

foreach ($cursor as $doc) {
    echo "Slug: " . $doc['slug'] . "\n";
}

Pros

  • Memory Efficiency: Only one document is loaded into memory at a time.
  • Streaming: Ideal for processing large datasets incrementally.

Cons

  • Single Use: Once a cursor is exhausted, it cannot be reused.
  • Less Convenient for Arrays: If you need all documents in an array, you must manually build it.

Building an Array with foreach

$documents = [];
foreach ($cursor as $doc) {
    $documents[] = $doc;
}

// Now $documents contains all documents
print_r($documents);

Key Differences: toArray() vs foreach

FeaturetoArray()foreach on Cursor
Memory UsageHigh (loads all documents into memory)Low (loads one document at a time)
Incremental Processing
Reusability✅ Can reuse the resulting array❌ Cursor is exhausted after iteration
Convenience✅ Directly get all documents as an array❌ Must manually build array if needed

When to Use Each

Use toArray() When:

  • You are working with small datasets.
  • You need all documents at once (e.g., for batch operations).
  • You want the convenience of an array for reuse or passing to functions.

Use foreach on the Cursor When:

  • You are processing large datasets.
  • You want to keep memory usage low.
  • You are performing streaming or incremental processing.

Practical Example: A Function Requiring an Array

Imagine you have a function that processes an array of documents:

function processDocuments(array $documents) {
    foreach ($documents as $doc) {
        echo $doc['slug'] . "\n";
    }
}

With toArray()

$documents = $cursor->toArray();
processDocuments($documents); // Directly pass the array

With foreach

$documents = [];
foreach ($cursor as $doc) {
    $documents[] = $doc; // Manually build the array
}
processDocuments($documents);

Conclusion

Both toArray() and foreach on the cursor are valid ways to process results from MongoDB's find() method. The choice depends on your use case:

  • For small datasets and convenience, use toArray().
  • For large datasets and memory efficiency, use foreach.

Understanding these differences can help you write more efficient and maintainable code. Happy coding!