I'd like to store the DocumentSet returned from Model::find() in memcached. However, I get the MongoException below when I try to work with the results after retrieving them from cache. Specifically, when using foreach, the exception is thrown when calling if ($this->_resource->hasNext())
on line 63 of \data\source\mongo_db\Result.php
MongoException
The MongoCursor object has not been correctly initialized by its constructor
I can understand why this would be the case.
My question is, is there anyway to pre-populate a Model::find() or create my own DocumentSet so that I can work with the data? Normally, I'd just convert it to an array and store that in cache. However, I need access to some of the Model methods I've written (ex: Customer::fullName())
Update: I've found a bit of a workound that is ok but not great. I'm saving the Model::find() results as an array in cache $result->to('array')
. Then, upon retrieval, I loop through the $results and populate a new array with Model::create($result, array("exists" => true)
for each $result;
A DocumentSet
returned by Model::find
contains a Mongo db cursor. It doesn't load all of the data from the database until the items are iterated. As each item is iterated, a Document
is created and is cached in memory into the DocumentSet object. The built-in php function iterator_to_array()
can be used to turn the DocumentSet into an array of documents which you could cache.
As you mention in your update, you can also use ->to('array')
to prepare for caching and then Model::create()
to build it back up. One caveat with that method: when you use ->to('array')
it also casts MongoId and MongoDate objects to strings and integers respectively. If you've defined a $_schema
for your model and set the 'id'
and 'date'
types, they will be cast back to the original MongoId and MongoDate objects in the Document returned by Model::create()
. If you don't have a schema for all of your fields, it can be a problem. I have a recent pull request that tries to make it possible to do ->to('array')
without casting the native mongo objects (also fixes a problem with the mongo objects always being casted when inside arrays of sub-documents).
FWIW, I actually prefer saving just the data in cache because it's less space than serializing a whole php object and avoids potential issues with classes not being defined or other items not initialized when the item is pulled from cache.
I haven't tried this... but I would think you could make a cache strategy class that would take care of this transparently for you. Another example of the great care that went into making Lithium a very flexible and powerful framework. http://li3.me/docs/lithium/storage/cache/strategy