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
DocumentSetreturned byModel::findcontains 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, aDocumentis created and is cached in memory into the DocumentSet object. The built-in php functioniterator_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 thenModel::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$_schemafor 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 byModel::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