MongoCursorException - Cursor not found (MongoDB PHP Driver)
Asked Answered
S

2

2

Code:

try {
  $documentsFind = $client->$db->$collection->find([
      // query
  ]);
  if ($documentsFind) {
    foreach ($documentsFind as $product) {
    // code...
    }
  }
catch (MongoCursorException $e) {
  echo "error message: ".$e->getMessage()."\n";
  echo "error code: ".$e->getCode()."\n";
}

Error:

Fatal error: Uncaught MongoDB\Driver\Exception\RuntimeException: Cursor not found, cursor id: 31837896248 in ...

It seems that the cursor does exist but times out? How can I prevent that from happening?

Edited to add: I tried doing:

 if ($documentsFind) {
    $documentsFind->immortal(true); // keep alive
    foreach ($documentsFind as $product) {
    // code...
    }
  }

But that results in Call to undefined method MongoDB\Driver\Cursor::immortal().

Sevenfold answered 16/6, 2016 at 22:5 Comment(2)
Does the error appears on the first run or are you able to load some entries?Friederike
It fetches quite a few documents from the DB but times out at some point. I was able to bypass this temporarily with mongod --setParameter cursorTimeoutMillis=9000000Sevenfold
N
7

Try querying like this:

$documentsFind = $client->$db->$collection->find([
  // query
], ['noCursorTimeout' => true]);

find() method passes the 2nd argument to the Find class constructor, so you can see all the available options here

Nympha answered 23/6, 2016 at 21:11 Comment(0)
Y
0

Cursor exception says,

The driver was trying to fetch more results from the database, but the database did not have a record of the query. This usually means that the cursor timed out on the server side: after a few minutes of inactivity, the database will kill a cursor.

The MongoDB PHP driver has two different timeouts:

  1. Connection timeout
  2. Cursor timeout

Make sure you use timeout or immortal on the cursor:

$cursor = $collection->find();
$cursor->immortal(true); 
$cursor->timeout(-1);

Note: Timeout indicates the time to wait on the client side while immortal sets the cursor on the server side.

But I would suggest if you have cursor of big data size then you should fetch cursor data in chunks like:

Get the first 1000 documents from collection, process them. Then get the next 1000 documents. You can do this by skip and limit.

Yoshikoyoshio answered 22/6, 2016 at 5:46 Comment(2)
Tried all of that. It appears that immortal and timeout are not available on the new PHP driver mongodb, not mongo.Sevenfold
Which mongodb version you are using? Are you getting cursor object for find()? Which php mongo driver you have? @3zzyYoshikoyoshio

© 2022 - 2024 — McMap. All rights reserved.